<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9133592462062635926</id><updated>2012-01-25T03:13:32.559Z</updated><category term='promotion'/><category term='facebook'/><category term='islam'/><category term='appstore'/><category term='meego'/><category term='javascript'/><category term='google maps'/><category term='html5'/><category term='php'/><category term='3d'/><category term='apple'/><category term='walkthrough'/><category term='quran project'/><category term='lipo'/><category term='fonts'/><category term='games dev'/><category term='music'/><category term='games'/><category term='youtube'/><category term='rejections'/><category term='open source'/><category term='osx'/><category term='softpoetry'/><category term='GL_TRIANGLES'/><category term='opengl es'/><category term='cute'/><category term='library'/><category term='obj'/><category term='android'/><category term='xcode'/><category term='opengl'/><category term='ios'/><category term='stock market hero'/><category term='software'/><category term='symbian'/><category term='shift it'/><category term='marketing'/><category term='uiwebview'/><category term='design'/><category term='GL_POLYGONS'/><category term='egypt'/><category term='prototypes'/><category term='canvas'/><category term='openal'/><category term='qt'/><category term='architecture'/><category term='igrapher'/><category term='json'/><title type='text'>Blog @SoftPoetry</title><subtitle type='html'>We write software.
We write games.
We write poetry.
@&lt;a href="http://softpoetry.com"&gt;SoftPoetry.com&lt;/a&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>61</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-6980017061202233774</id><published>2012-01-25T03:13:00.001Z</published><updated>2012-01-25T03:13:32.568Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='walkthrough'/><category scheme='http://www.blogger.com/atom/ns#' term='shift it'/><category scheme='http://www.blogger.com/atom/ns#' term='osx'/><title type='text'>Shift It+ for OSX</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;br /&gt;Windows 7 has a great windows shifting mechanic for quickly splitting windows around the screen, to be able to use applications side by side.&lt;br /&gt;&lt;br /&gt;For OSX I found an Open Source solution here.&lt;br /&gt;&lt;a href="http://code.google.com/p/shiftit/"&gt;http://code.google.com/p/shiftit/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It wasn't perfect for my needs, so I forked the source code primarily to add multiple monitor support, and more customized controls which didn't conflict with the applications I used.&lt;br /&gt;&lt;br /&gt;Here is the presentation of the current features.&lt;br /&gt;&lt;iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/JfR40FkUCbY" width="420"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Here is a walkthrough of the source code so you can quickly jump in and add your own customizations.&lt;/div&gt;&lt;iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/Jbi0S2hob_s" width="420"&gt;&amp;amp;amp;lt;p&amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;lt;p&amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;You &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;lt;/p&amp;amp;amp;gt;&lt;/iframe&gt;&lt;/div&gt;&lt;br /&gt;Feel free to grab the forked source code here.&lt;br /&gt;&lt;a href="https://github.com/ashcairo/ShiftItPlus"&gt;https://github.com/ashcairo/ShiftItPlus&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-6980017061202233774?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/6980017061202233774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2012/01/shift-it-for-osx.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6980017061202233774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6980017061202233774'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2012/01/shift-it-for-osx.html' title='Shift It+ for OSX'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/JfR40FkUCbY/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-6213528091844194161</id><published>2011-12-29T16:41:00.002Z</published><updated>2011-12-30T18:13:41.025Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='promotion'/><category scheme='http://www.blogger.com/atom/ns#' term='appstore'/><category scheme='http://www.blogger.com/atom/ns#' term='marketing'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>How to fail at promoting your Android App</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;I'm not a markerteer, I'm a developer. I like creating things then showing them off for better or worse reactions (usually worse). For my 9-5, we've been given the opportunity to work on and release side projects to the Android market. After releasing an app on there, I wanted to try to figure out how to go about getting it downloaded by people.&lt;br /&gt;&lt;br /&gt;The market I was going for was going to be a challenge, the app enables people to create lip sync videos, this obviously narrows down your userbase from predominantly content consumers to content creators. Nevertheless, I googled how to promote your app and really, it seemed there wasn't much resources out there, other than a &lt;a href="http://stackoverflow.com/questions/4058297/how-to-promote-android-app" target="_blank"&gt;stackoverflow post from 2008&lt;/a&gt; (perhaps I'm suffering from a &lt;a href="http://blog.ted.com/2011/05/02/beware-online-filter-bubbles-eli-pariser-on-ted-com/" target="_blank"&gt;search bubble&lt;/a&gt;?). So here are the aproaches I tried and their results.&lt;br /&gt;&lt;br /&gt;DISCLAIMER: I am not a markerteer, I just did this as a fun learning exercise.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Attempt 1: Social Networks&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;So step one for me was to talk to my friends and tell them how awesome my app was and how they needed to download it right now. I posted it on my Facebook wall and Tweeted about it. (I didn't go hyperbolic about it, just one single quirky post.)&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-YRBToqQSRV0/TvyUmkrzmJI/AAAAAAAAAJc/Tx8Iw9T2NbU/s1600/ScreenShot005.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="201" src="http://4.bp.blogspot.com/-YRBToqQSRV0/TvyUmkrzmJI/AAAAAAAAAJc/Tx8Iw9T2NbU/s320/ScreenShot005.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Results: This generated around 50 downloads and a bunch (~10) of good reviews.&lt;br /&gt;Cost: £0. &lt;br /&gt;Conclusion: Good for good reviews, perhaps I could of spammed my friends more.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Attempt 2: &lt;/b&gt;&lt;b&gt;Blogs&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;There are a lot of Android blogs out there, so googled Android blogs, and e-mailed the reviewers asking them to review the app. I recieved some generic replies asking me for money for their premium review service, which I ignored. But, perhaps I'll try this out in future.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-OeMDPPtCdl8/TvyVFgauMZI/AAAAAAAAAJo/jeZgzgbB4gM/s1600/ScreenShot007.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="109" src="http://3.bp.blogspot.com/-OeMDPPtCdl8/TvyVFgauMZI/AAAAAAAAAJo/jeZgzgbB4gM/s320/ScreenShot007.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Results: 0 downloads.&lt;br /&gt;Cost: £0.&lt;br /&gt;Conclusions: I should investigate a premium review. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Attempt 3: &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: large;"&gt;Ad Networks&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Facebook&lt;/b&gt;&lt;br /&gt;Facebook is great for targeting the users you want to see your advert, you can select your age demographic, gender and interests. You can't select multiple interests, it either someone who loves music OR someone who loves Android, not both. Felt like a bad idea. I initially targetted Android users, but no one wanted to click my advert. I expanded to music, but still hardly anyone wanted to click my advert.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-YYXjF6UVscY/TvyVNo9qmYI/AAAAAAAAAJ0/eoNsH9lFCis/s1600/ScreenShot002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-YYXjF6UVscY/TvyVNo9qmYI/AAAAAAAAAJ0/eoNsH9lFCis/s1600/ScreenShot002.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The advert took around a day to verify, and there was no minimum pre-payment, you're charged after.&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;Results: 47 clicks. ~0 downloads&lt;br /&gt;Cost: £4.71.&lt;br /&gt;Conclusions: Perhaps people are just too educated to the advert placements that they just filter them out, that's what I do. Or most likely my advert creating skills are poor.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Adwords&lt;/b&gt;&lt;br /&gt;Let's you specify lots of keywords for your campaign, which, is ok. Can't target users like Facebook, but the main problem here was that keywords simply cost too much. A targeted keyword ranged between £1.50 to £2.50. This was too much for my beliefs, so I set it to £0.50. Of course, no one clicked on the targeted keywords. But the budgeted money magically disappeared at the end of the week from their 'Display Network' which charged £0.07 per click.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-gDobQIXdfgo/TvyVS9QpKYI/AAAAAAAAAKA/QaaV4tAJW-8/s1600/ScreenShot006.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="61" src="http://3.bp.blogspot.com/-gDobQIXdfgo/TvyVS9QpKYI/AAAAAAAAAKA/QaaV4tAJW-8/s320/ScreenShot006.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The advert took around a few days to verify, and the minimum pre-payment is £10.00.&lt;br /&gt;&lt;br /&gt;Results: 142 clicks. ~0 downloads.&lt;br /&gt;Cost: £10.00&lt;br /&gt;Conclusions: Not convinced this is the right way to go.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Admob&lt;/b&gt;&lt;br /&gt;Google's other advertising platform is more interesting. You can target the phone and OS, not so much the interests or user age like Facebook, but you can really pick out a phone that you know works with your app. Since you can get a few disheartening 1/5 stars from one of the hundreds of customized Android devices that you never managed to test your application on and discover that it doesn't function correctly on that device.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-vvmgqsIMU3w/TvyVaK9PDZI/AAAAAAAAAKM/wuVtpANnTSw/s1600/ScreenShot004.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="185" src="http://4.bp.blogspot.com/-vvmgqsIMU3w/TvyVaK9PDZI/AAAAAAAAAKM/wuVtpANnTSw/s320/ScreenShot004.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Also note when specifying the region, it's probably best to decouple your adverts into individual regions to keep the minimum cost per click low. As if you select UK on it's own, its $0.05 per click, if you select USA on it's own, it's $0.15 per click, if you select them both it jumps to $0.25, if you add in Japan it'll jump to $0.76.&lt;br /&gt;&lt;br /&gt;The advert took a week to verify and the minimum pre-payment is $50.00.&lt;br /&gt;&lt;br /&gt;Results: So far after a day of heavily targetted advertising (region+device) we've had 310 impressions and 0 clicks.&lt;br /&gt;Cost:$0.00 ($50.00 pre-payment)&lt;br /&gt;Conclusions: I like how you can pick which OS and phone you want to target. Probably can get more with different regions targetted.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;AppBrain&lt;/b&gt;&lt;br /&gt;This service allows you to pay per install, which is great to boost your download figures at the least. There's no OS/phone filtering or demographic selection. The recommended cost per install is $0.60, and the minimum is $0.20, I went with $0.20. &lt;br /&gt;&lt;br /&gt;Initially the app wasn't on their directory, but I e-mailed them and they added it within a day. The minimum pre-payment is $100&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-qDtGW9NbuxY/Tv365S9XRXI/AAAAAAAAAKY/EthPEjQ-jzM/s1600/ScreenShot002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-qDtGW9NbuxY/Tv365S9XRXI/AAAAAAAAAKY/EthPEjQ-jzM/s1600/ScreenShot002.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Results: It's only been a day, we've had 1,289 impressed, 22 clicks and only 3 installs. We did get an extra rating during that period; a bad rating&lt;i&gt;.&lt;/i&gt;&lt;br /&gt;Cost: $0.60 ($100 pre-payment).&lt;br /&gt;Conclusions: At least it's a gauranteed install your paying for. Although if you're releasing an app which hasn't been tested on every single Android device out there and has a risk of not running on one of them (i.e. uses Camera API/NDK/OpenGL), you may get some negative reviews.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Others?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;Open Source&lt;/b&gt;&lt;br /&gt;I like open sourcing things, I hear it can also promote your app virally via the developer community. In future I plan on open sourcing the source code to provide an explaination on how the code works. However, as it's a work project, I'll need to go through a couple of check points before getting this done.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Everbadge&lt;/b&gt;&lt;br /&gt;Another pay per install service, however it seems to require an SDK for app download verification. The app was already released, and I couldn't add the SDK at this stage.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;Of course, real life advertising would require a much bigger budget than I was prepared to sacrifice for my experiment. But, I thought this post may be interesting to small time developers like me. In the end, I am not a markerteer.&lt;b&gt; &lt;/b&gt;But, if you have any suggestions, please leave a comment.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-6213528091844194161?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/6213528091844194161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/12/how-to-fail-at-promoting-your-android.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6213528091844194161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6213528091844194161'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/12/how-to-fail-at-promoting-your-android.html' title='How to fail at promoting your Android App'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-YRBToqQSRV0/TvyUmkrzmJI/AAAAAAAAAJc/Tx8Iw9T2NbU/s72-c/ScreenShot005.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-5308648227020339161</id><published>2011-12-26T07:12:00.000Z</published><updated>2011-12-26T07:33:38.937Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='open source'/><category scheme='http://www.blogger.com/atom/ns#' term='islam'/><category scheme='http://www.blogger.com/atom/ns#' term='GL_POLYGONS'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='obj'/><category scheme='http://www.blogger.com/atom/ns#' term='quran project'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl es'/><category scheme='http://www.blogger.com/atom/ns#' term='GL_TRIANGLES'/><title type='text'>Quran Project - Loading 3D Obj Models</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Reading e-books is like eating marmite. You either love it or hate it. Myself personally, I read lots of articles, but never have the attention span to get through a book. Currently we're working together with the Quran Project charity (&lt;a href="http://quranproject.org/"&gt;http://quranproject.org&lt;/a&gt;) in trying to re-create your typical reading experience into something more as an interactive 3d novel. The basic idea being that you get to browse the different chapters of the book, by swiping through different scenery and animations that hopefully entice you to read on more than perhaps you normally would.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-I-vFLZHQwqU/Tvgcdux1ugI/AAAAAAAAAIg/JNzAIxHyi1k/s1600/quran_stand_v02.1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/-I-vFLZHQwqU/Tvgcdux1ugI/AAAAAAAAAIg/JNzAIxHyi1k/s320/quran_stand_v02.1.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Working along with a 3d artist has it's challenges, ranging from getting your naming conventions right to importing the assets created.&lt;br /&gt;&lt;br /&gt;The models I'm working with have been exported from Maya as obj files. In the past I'd write my own exporter into my own personal favoured file format. However, I took this opportunity, to go with the flow for compatibility reasons and work on getting obj files imported into the application engine I'm working with.&lt;br /&gt;&lt;br /&gt;I found a great ObjLoader tutorial series online here (&lt;a href="http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www"&gt;http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www&lt;/a&gt;), I tested out the provided tutorials with the model exported and found that tutorial3 was everything I needed to get to the obj description.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-oY8ZTIW6OwY/Tvgcj_jICAI/AAAAAAAAAIs/b2K9NBzwGqA/s1600/ScreenShot005.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://4.bp.blogspot.com/-oY8ZTIW6OwY/Tvgcj_jICAI/AAAAAAAAAIs/b2K9NBzwGqA/s320/ScreenShot005.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Integrating the objloader header and cpp file into an iOS project can be done with minimal changes to get it compiling. Those being to comment out win32 specific includes and switch from the OpenGL method of drawing polygons using glBegin and glEnd, into an OpenGL ES compatible vertex array using GL_TRIANGLES.&lt;br /&gt;&lt;br /&gt;So the first step would be to take the loaded in vertices and draw them using OpenGL ES's GL_TRIANGLE construct, but of course this would lead to an incomplete scene.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-XCpSXDj52OQ/TvgczhahBCI/AAAAAAAAAI4/JpatPUQkpxI/s1600/iOS+Simulator+Screen+shot+26+Dec+2011+05.52.06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-XCpSXDj52OQ/TvgczhahBCI/AAAAAAAAAI4/JpatPUQkpxI/s320/iOS+Simulator+Screen+shot+26+Dec+2011+05.52.06.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;What we need to do is switch from OpenGL's GL_POLYGONS to OpenGL ES' GL_TRIANGLES. To do so we can create a triangles from the first vertex and remaining vertices of the polygon.&lt;br /&gt;&lt;br /&gt;As in if we have a 5 sided polygon.&lt;br /&gt;We'll make a triangle from the first three vertices (v1, v2, v3).&lt;br /&gt;Then, the first vertex and the next two (v1, v3, v4).&lt;br /&gt;Then finally, the first vertex and the last two (v1, v4, v5).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-i2oyqwO2Pmg/TvgdyBQKdbI/AAAAAAAAAJE/aJv11_YpSSc/s1600/iOS+Simulator+Screen+shot+26+Dec+2011+06.30.26.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-i2oyqwO2Pmg/TvgdyBQKdbI/AAAAAAAAAJE/aJv11_YpSSc/s320/iOS+Simulator+Screen+shot+26+Dec+2011+06.30.26.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;You can grab the source code from the Open Source cross platform application framework (&lt;a href="https://github.com/OrangeLabsUK/2c"&gt;https://github.com/OrangeLabsUK/2c&lt;/a&gt;) with the file to watch out for being CCModelObj.cpp.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-5308648227020339161?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/5308648227020339161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/12/quran-project-loading-3d-obj-models.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5308648227020339161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5308648227020339161'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/12/quran-project-loading-3d-obj-models.html' title='Quran Project - Loading 3D Obj Models'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-I-vFLZHQwqU/Tvgcdux1ugI/AAAAAAAAAIg/JNzAIxHyi1k/s72-c/quran_stand_v02.1.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-5767104230271189780</id><published>2011-10-19T22:30:00.000+01:00</published><updated>2011-10-19T22:30:18.674+01:00</updated><title type='text'>Social Poetry - Open Sourced</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;FaceStalker the working title for the SocialPoetry project has gone gold across three platforms. To mark the approval for the iPhone, Android and Windows versions, the source code has been open sourced on GitHub.&lt;br /&gt;&lt;br /&gt;All links to download the app and source code for the relevant platforms can be found here: &lt;a href="http://softpoetry.com/projects/facestalker/"&gt;http://softpoetry.com/projects/facestalker/&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-5767104230271189780?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/5767104230271189780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/10/social-poetry-open-sourced.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5767104230271189780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5767104230271189780'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/10/social-poetry-open-sourced.html' title='Social Poetry - Open Sourced'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-3445988875699999329</id><published>2011-10-02T10:27:00.000+01:00</published><updated>2011-10-02T10:27:09.235+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='meego'/><category scheme='http://www.blogger.com/atom/ns#' term='3d'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='symbian'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Social Poetry release candidate</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;The social poetry project that was conceptualised a &lt;a href="http://blog.softpoetry.com/2011/07/social-poetry-first-prototype.html"&gt;couple of months ago&lt;/a&gt;&lt;span id="goog_2037573630"&gt;&lt;/span&gt;&lt;span id="goog_2037573631"&gt;&lt;/span&gt;, has finally hit its release candidate milestone. Over the next coming weeks, it will be submitted to the relevant app stores. This app has been written as a showcase for a soon to be released open source cross platform 3d application development framework, so the actual source code for it will also be released very soon.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-j0BsgkcMQ0s/Togtde3fbxI/AAAAAAAAAHw/1fGu3rQ6btg/s1600/iTunes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-j0BsgkcMQ0s/Togtde3fbxI/AAAAAAAAAHw/1fGu3rQ6btg/s320/iTunes.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://softpoetry.com/projects/facestalker"&gt;http://softpoetry.com/projects/facestalker&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-3445988875699999329?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/3445988875699999329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/10/social-poetry-release-candidate.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3445988875699999329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3445988875699999329'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/10/social-poetry-release-candidate.html' title='Social Poetry release candidate'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-j0BsgkcMQ0s/Togtde3fbxI/AAAAAAAAAHw/1fGu3rQ6btg/s72-c/iTunes.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-3938527770127306384</id><published>2011-07-20T23:57:00.003+01:00</published><updated>2011-07-21T02:38:52.726+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='architecture'/><title type='text'>Rapid Software Architecture Design Tools</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;In an ideal world you'd want design the system architecture first, then program in conformance to the architecture design. Back in University I used tools such as Rational Rose for modelling UML class interaction diagrams. This was great to be able to detail in what classes you've decided to use post-design and to get a good mark from my tutor. But, for the actual design process it was slow, unintuitive, boring and a pain to deal with. Pen and paper for rapid prototyping was my best friend in discovering the best architecture to go with.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-hVIOlo-QgZA/Tico0a51cqI/AAAAAAAAAF8/TxxWlEK4KBc/s1600/IMG_0079.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="http://2.bp.blogspot.com/-hVIOlo-QgZA/Tico0a51cqI/AAAAAAAAAF8/TxxWlEK4KBc/s320/IMG_0079.JPG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Now say hello to the world of cutting edge software, where new system constraints are being discovered as these systems are built and interact with each other. You end up constantly re-designing your architecture to fit in with these constrains, which means the actual step of modelling your architecture on a tool such as Rational Rose becomes a fad.&lt;br /&gt;&lt;br /&gt;When modelling your architecture becomes a second thought, you lose the ability to effectively communicate to other developers and project managers how a system works and what the cost would be of developing new features to the software. This is bad. There has to be a better way.. What we need is rapid software architecture design tools.&lt;br /&gt;&lt;br /&gt;So in this effort to discover such a tool, I've shortlisted the following tools for trialing.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-zyl2vGV2zLI/TicoLtJIj7I/AAAAAAAAAF4/cYh4QB4Pfy0/s1600/Screen+shot+2011-07-20+at+20.09.06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="184" src="http://3.bp.blogspot.com/-zyl2vGV2zLI/TicoLtJIj7I/AAAAAAAAAF4/cYh4QB4Pfy0/s320/Screen+shot+2011-07-20+at+20.09.06.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Microsoft Visio (Windows, commercial)&lt;/li&gt;&lt;li&gt;yEd (Windows/OSX/Linux, free)&lt;/li&gt;&lt;li&gt;GraphViz (Windows/OSX/Linux, free)&lt;/li&gt;&lt;li&gt;Dia (Windows/OSX/Linux, free)&lt;/li&gt;&lt;li&gt;Visual Paradigm (Windows/OSX/Linux, commercial)&lt;/li&gt;&lt;li&gt;Enterprise Architect (Windows, commercial)&amp;nbsp;&lt;/li&gt;&lt;li&gt;OmniGraffle (Mac, commercial) &lt;/li&gt;&lt;/ul&gt;Now remember, the use case of this tool is to re-architect systems more intuitively than using a pen and paper. I will be very harsh in my scoring, as I will to stress, I will be comparing these tools to using a pen and paper.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Microsoft Visio 2003&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-ILQiM4tF05Y/Ticjc6cYWlI/AAAAAAAAAF0/xrzedMMx3yg/s1600/Screen+shot+2011-07-20+at+19.47.17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="230" src="http://4.bp.blogspot.com/-ILQiM4tF05Y/Ticjc6cYWlI/AAAAAAAAAF0/xrzedMMx3yg/s320/Screen+shot+2011-07-20+at+19.47.17.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I'd heard great things on this tool. Firstly it's the recommended tool of choice as my company has a license for it, mind you it's only a licence for the 2003 edition. Now, I really really hope they've improved on it since then because using this tool is like having your eyelids pierced while watching a Justin Bieber music video. It is so UGLY. UGLY to use, UGLY to look at. The lines are rigid, the connection sections stand out too much, a dialog box pops up just to rename a class. Even if I managed to model the most intricate architecture in the world ever with this tool after years of practice, if I showed the results to someone, they'd probably stab their eyeballs out as relief from looking at this monstrosity. &lt;br /&gt;&lt;br /&gt;Score: 0/5&lt;br /&gt;Please don't use or recommend this software.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;yEd&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-AJv6d1mhXIk/Ticrb0gE4MI/AAAAAAAAAGA/AaWl1iO1w64/s1600/Screen+shot+2011-07-20+at+20.24.11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="209" src="http://1.bp.blogspot.com/-AJv6d1mhXIk/Ticrb0gE4MI/AAAAAAAAAGA/AaWl1iO1w64/s320/Screen+shot+2011-07-20+at+20.24.11.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I'm using the mac version and it looks and feels pretty dated. I don't understand why the class boxes don't resize if you give them a name that doesn't fit the box. Panning is unintuitive. Creating arrows is a mystery, and it seems to like creating classes every time you left click the mouse. Well, at least it's nicer to look at than Visio.&lt;br /&gt;&lt;br /&gt;Score: 2/5&lt;br /&gt;Has potential, may come back to using this later.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;GraphViz&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-09hNCjaA-lA/TicuGq50D1I/AAAAAAAAAGE/bXY5sCqHKjc/s1600/Screen+shot+2011-07-20+at+20.35.06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://2.bp.blogspot.com/-09hNCjaA-lA/TicuGq50D1I/AAAAAAAAAGE/bXY5sCqHKjc/s320/Screen+shot+2011-07-20+at+20.35.06.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I've kind of used this tool before when generating a DOXYGEN, well not really. The doxygen tools generated the chart automatically and I did nothing. My gut tells me that this tool will be useless unless you're a command line VIM junkie.. My gut was right. I have no idea how to use this tool to create charts. When you launch it, the an open file dialog box appears. If you have any clue as to how to create charts using this tool. Please let me know.&lt;br /&gt;&lt;br /&gt;Score: -1/5&lt;br /&gt;Waste your time with Microsoft Visio.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Dia&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-FmA7adzbUOM/Ticv8-kJLyI/AAAAAAAAAGI/f2l74cveR5k/s1600/Screen+shot+2011-07-20+at+20.40.38.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="163" src="http://2.bp.blogspot.com/-FmA7adzbUOM/Ticv8-kJLyI/AAAAAAAAAGI/f2l74cveR5k/s320/Screen+shot+2011-07-20+at+20.40.38.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;It's almost as ugly as Visio. The OSX version feels like a hack, with the shortcut keys being all wrong. When you move a class, the arrows don't follow. The lines can be diagnal, but the classes don't lock inline with other classes so it gets pretty messy, pretty quick.&lt;br /&gt;&lt;br /&gt;Score: 1/5&lt;br /&gt;It's free, but other than that I have no iDia why I'd use this tool.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Visual Paradigm &amp;amp; Agilian&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-UfYYCzUseT0/TidE3HApMnI/AAAAAAAAAGU/cbc0DtC6nB4/s1600/Screen+shot+2011-07-20+at+22.12.30.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="199" src="http://4.bp.blogspot.com/-UfYYCzUseT0/TidE3HApMnI/AAAAAAAAAGU/cbc0DtC6nB4/s320/Screen+shot+2011-07-20+at+22.12.30.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Agilian popped up when installing Visual Paradigm, it claimed to be the solution for agile software development, so with the buzz on Scrum going on I picked to install that. Looks like Eclipse, feels like Eclipse, when I tried to draw a class diagram, the UML class toolbox was empty, reappeared later though, but you get the idea that it's buggy. Suffers from the same issue of not resizing a class box when you input a long name. Doesn't provide indicator lines when placing a class down for the first time, so you always have to place a class down, rename it, then replace it again. Gets a bit too excited when placing down associations, as in, you place one down, it places it wrongly, you try to drag it to the right place, but instead it decides to turn into a game of Snake. I give up with this, there has to be something better.&lt;br /&gt;&lt;br /&gt;Score: 0/5&lt;br /&gt;I can't believe people actually pay to be tortured.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enterprise Architect&lt;/b&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Tu0czrIBXsc/TidHCpmyoeI/AAAAAAAAAGY/DJOYeWIWVQk/s1600/Screen+shot+2011-07-20+at+22.21.11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-Tu0czrIBXsc/TidHCpmyoeI/AAAAAAAAAGY/DJOYeWIWVQk/s1600/Screen+shot+2011-07-20+at+22.21.11.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/-Ra9FPxHH3LM/TidUlEUgpHI/AAAAAAAAAGc/DM7GLj4kTy0/s1600/Screen+shot+2011-07-20+at+23.13.32.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="164" src="http://4.bp.blogspot.com/-Ra9FPxHH3LM/TidUlEUgpHI/AAAAAAAAAGc/DM7GLj4kTy0/s320/Screen+shot+2011-07-20+at+23.13.32.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;While the website looks like the kind of thing mothers of the future  will be teaching their children to stay away from. With their malware  inspired use of stock photos of corporation towers and business executives shaking  hands. My workmate said that he loved it, and it did the job really well. On launch it asks you which version you want to use, Professional, Enterprise, Business, blah blah, listing no feature differences.. Whatever, I went with Business and Software Engineering. The interface looks a lot like Microsoft Visual Studio 2010, which is a good thing. The class boxes are shaded, which means that it'll impress project managers who are used to looking at shaded PowerPoint boxes. Well, that's enough of the good. The text is too small, creating links between classes is a pain, you drag one between classes then you have to select the connection type from a drop down, very cumbersome. I quizzed my workmate on this and he admitted that he had only used it once.. a long time ago.. to impress his boss.&lt;br /&gt;&lt;br /&gt;Score: 1/5&lt;br /&gt;Packed with so much features that you will never use.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;OmniGraffle&lt;/b&gt;&lt;br /&gt;Macintosh fan boys love this tool. I'm on a MacBook Pro, so why not me? Oh my god, there's a cloud chart. Seriously! Look..&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-9IzvelrAgEY/TidXsCGY1vI/AAAAAAAAAGk/LVCEKc-JKb8/s1600/Screen+shot+2011-07-20+at+23.33.02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="271" src="http://4.bp.blogspot.com/-9IzvelrAgEY/TidXsCGY1vI/AAAAAAAAAGk/LVCEKc-JKb8/s320/Screen+shot+2011-07-20+at+23.33.02.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Not really useful for the class connections, but it is pretty fun to use. Ok, what about for a proper class diagram? Well, there's no class diagram option in the menu, but surprisingly enough you can import a xCode project. The parser only works on Objective C classes which is pretty limited and modifying the class contents is challenging. Overall, it's really more of a drawing tool than for classes which is a real shame.&lt;br /&gt;&lt;br /&gt;Score: 2/5&lt;br /&gt;Shame it's not built for software architecture diagrams.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;I give up. Pen and paper is the way to go for rapid design. For software architecture modelling (after you've got a good sense of the design), I think I'll go back to &lt;b&gt;yEd&lt;/b&gt; and give that another spin.&lt;br /&gt;&lt;b&gt; &lt;/b&gt;&lt;br /&gt;If you have any suggestions for good software design tools, please let me know. I'm desperate..&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-3938527770127306384?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/3938527770127306384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/07/rapid-software-architecture-design.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3938527770127306384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3938527770127306384'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/07/rapid-software-architecture-design.html' title='Rapid Software Architecture Design Tools'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-hVIOlo-QgZA/Tico0a51cqI/AAAAAAAAAF8/TxxWlEK4KBc/s72-c/IMG_0079.JPG' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-4268316287692834586</id><published>2011-07-11T03:08:00.005+01:00</published><updated>2011-07-13T02:55:54.731+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><title type='text'>From lib_json to Jansson</title><content type='html'>I love homogeneity when it comes to developing software. Sure, heterogeneity is required when dealing with undefined cutting edge high performance systems. But for application development, where software elegance and maintainability are key. You really don't want to tie yourself down to platform specific libraries especially in the current "App" world where you want to hit as many platforms as possible. This is why I recently switched to Jansson for my JSON parsing needs.&lt;br /&gt;&lt;br /&gt;Jansson is a C JSON library which doesn't depend on other libraries, so if like me you need something to run on Android's NDK which doesn't support STL, you want to be using this.&lt;br /&gt;&lt;a href="http://www.digip.org/jansson/"&gt;http://www.digip.org/jansson/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Since I find sample code to be the easiest way of picking up a new library..&lt;br /&gt;&lt;br /&gt;Here is example code showing you how to parse your friends list from Facebook's graph api using lib_json.&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; #include "json.h"  &lt;br /&gt;   &lt;br /&gt; ...  &lt;br /&gt;   &lt;br /&gt; std::string jsonResponse( reply-&amp;gt;data.buffer );  &lt;br /&gt; Json::Value root;  &lt;br /&gt; Json::Reader reader;  &lt;br /&gt; const BOOL parsingSuccessful = reader.parse( jsonResponse, root );  &lt;br /&gt; ASSERT( parsingSuccessful );  &lt;br /&gt; if( parsingSuccessful )  &lt;br /&gt; {  &lt;br /&gt;   const Json::Value jsonData = root["data"];  &lt;br /&gt;   const uint length = jsonData.size();  &lt;br /&gt;     &lt;br /&gt;   for( uint i=0; i&amp;lt;length; ++i )  &lt;br /&gt;   {  &lt;br /&gt;     Json::Value text = jsonData[i];  &lt;br /&gt;       &lt;br /&gt;     std::string jsonStringName = text["name"].asString();  &lt;br /&gt;     std::string jsonStringID = text["id"].asString();  &lt;br /&gt;       &lt;br /&gt;     // We can now do something with our Name and ID  &lt;br /&gt;   }  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Here is example code showing you how to parse your friends list from Facebook's graph api Jansson.&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; #include "jansson.h"  &lt;br /&gt;   &lt;br /&gt; ...  &lt;br /&gt;   &lt;br /&gt; json_error_t error;  &lt;br /&gt; json_t *root = json_loads( reply-&amp;gt;data.buffer, 0, &amp;amp;error );  &lt;br /&gt; if( root )  &lt;br /&gt; {  &lt;br /&gt;   json_t *jsonData = json_object_get( root, "data" );  &lt;br /&gt;   if( json_is_array( jsonData ) )  &lt;br /&gt;   {  &lt;br /&gt;     const uint length = json_array_size( jsonData );  &lt;br /&gt;     for( uint i=0; i&amp;lt;length; ++i ) // Iterates over the sequence elements.  &lt;br /&gt;     {  &lt;br /&gt;       json_t *jsonObject = json_array_get( jsonData, i );  &lt;br /&gt;         &lt;br /&gt;       json_t *jsonID = json_object_get( jsonObject, "id" );  &lt;br /&gt;       const char *jsonStringID = json_string_value( jsonID );  &lt;br /&gt;         &lt;br /&gt;       json_t *jsonName = json_object_get( jsonObject, "name" );  &lt;br /&gt;       const char *jsonStringName = json_string_value( jsonName );  &lt;br /&gt;         &lt;br /&gt;       // We can now do something with our Name and ID  &lt;br /&gt;     }  &lt;br /&gt;   }  &lt;br /&gt;   json_decref( root ); &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-C8g9YtPZRNA/ThpcTFck8wI/AAAAAAAAAFw/Z5NJWn0qfS8/s1600/ScreenShot001.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="182" width="320" src="http://1.bp.blogspot.com/-C8g9YtPZRNA/ThpcTFck8wI/AAAAAAAAAFw/Z5NJWn0qfS8/s320/ScreenShot001.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;center&gt;Piece of cake :)&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-4268316287692834586?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/4268316287692834586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/07/from-libjson-to-jansson.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4268316287692834586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4268316287692834586'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/07/from-libjson-to-jansson.html' title='From lib_json to Jansson'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-C8g9YtPZRNA/ThpcTFck8wI/AAAAAAAAAFw/Z5NJWn0qfS8/s72-c/ScreenShot001.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-7758815304665963713</id><published>2011-07-02T03:38:00.006+01:00</published><updated>2011-07-02T03:55:35.888+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='meego'/><category scheme='http://www.blogger.com/atom/ns#' term='3d'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='symbian'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Social Poetry - First Prototype</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-QsZbq6gw1rM/Tg6FSw2nigI/AAAAAAAAAFg/A7xiq5sNXb8/s1600/Screen%2Bshot%2B2011-07-02%2Bat%2B03.40.34.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="249" width="320" src="http://3.bp.blogspot.com/-QsZbq6gw1rM/Tg6FSw2nigI/AAAAAAAAAFg/A7xiq5sNXb8/s320/Screen%2Bshot%2B2011-07-02%2Bat%2B03.40.34.png" /&gt;&lt;/a&gt;&lt;/div&gt;I spend a lot of my life on Facebook, it's great what they've done with social networking. But, I've always found quirks in the user experience. I've been lately imagining a world where I could easily run through my friends lists, see the status updates and photo galleries in a minority report inspired way. It really irks me that such beautiful beautiful user generated data is only really being exploited by stupid social games like Farmville.. Grr.&lt;br /&gt;I hate Farmville.&lt;br /&gt;&lt;br /&gt;So last weekend I set myself the challenge of seeing what I could do with the Facebook APIs, and the following video presents the outcome.&lt;br /&gt;&lt;br /&gt;&lt;iframe width="560" height="349" src="http://www.youtube.com/embed/m88faAA2Cnc" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;I'm pretty busy this weekend, but I plan on getting at the very least a photo gallery viewer for all my friends.&lt;br /&gt;&lt;br /&gt;Currently I'm targeting Qt for the prototype as I'm initially tailoring it as a Desktop Windows/Mac prototype. However as the codebase is based off OpenGL, I have got it running on iPhone and Android.&lt;br /&gt;&lt;br /&gt;If you're interested in this project, let me know and I'll be happy to give you an early release.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-7758815304665963713?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/7758815304665963713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/07/social-poetry-first-prototype.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7758815304665963713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7758815304665963713'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/07/social-poetry-first-prototype.html' title='Social Poetry - First Prototype'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-QsZbq6gw1rM/Tg6FSw2nigI/AAAAAAAAAFg/A7xiq5sNXb8/s72-c/Screen%2Bshot%2B2011-07-02%2Bat%2B03.40.34.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-3658563243479592536</id><published>2011-07-01T01:14:00.004+01:00</published><updated>2011-07-02T03:31:03.067+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='games dev'/><category scheme='http://www.blogger.com/atom/ns#' term='egypt'/><title type='text'>Freedom Square</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;This 4th of July the Americans won't be the only ones out in the streets with something to celebrate about..&lt;br /&gt;&lt;a href="http://softpoetry.com/projects/tahrirsquare/" target="_blank"&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://softpoetry.com/projects/tahrirsquare/" target="_blank"&gt;&lt;img border="0" height="320" src="http://softpoetry.com/projects/tahrirsquare/images/splash.png" width="320" /&gt;&lt;br /&gt;Download Here&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The game that should not have been made will be available &lt;b&gt;for one day and one day only&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;iframe allowfullscreen="" frameborder="0" height="349" src="http://www.youtube.com/embed/Sb6gXYIcZBM" width="560"&gt;&lt;/iframe&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-3658563243479592536?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/3658563243479592536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/07/freedom-square.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3658563243479592536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3658563243479592536'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/07/freedom-square.html' title='Freedom Square'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/Sb6gXYIcZBM/default.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-4600556694650183679</id><published>2011-05-28T13:17:00.007+01:00</published><updated>2011-05-28T13:35:51.988+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='appstore'/><category scheme='http://www.blogger.com/atom/ns#' term='rejections'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>AppStore Rejections Are Sometimes A Good Thing</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-p6xDy67fMEM/TeDo-DINnCI/AAAAAAAAAD4/QalkHAiQ2nE/s1600/ScreenShot002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-p6xDy67fMEM/TeDo-DINnCI/AAAAAAAAAD4/QalkHAiQ2nE/s640/ScreenShot002.png" width="600" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-4600556694650183679?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/4600556694650183679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/05/why-appstore-rejections-are-sometimes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4600556694650183679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4600556694650183679'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/05/why-appstore-rejections-are-sometimes.html' title='AppStore Rejections Are Sometimes A Good Thing'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-p6xDy67fMEM/TeDo-DINnCI/AAAAAAAAAD4/QalkHAiQ2nE/s72-c/ScreenShot002.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-8845477576525123127</id><published>2011-05-24T07:04:00.001+01:00</published><updated>2011-05-24T07:04:40.709+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='games dev'/><category scheme='http://www.blogger.com/atom/ns#' term='egypt'/><title type='text'>Tahrir Square II: He's Back!</title><content type='html'>Well it's finally done! After spending the last three weekends stoned out on the concept. I can finally play as a cybernetic Egyptian dictator.&lt;br /&gt;&lt;br /&gt;Watch the trailer and give me your feedback on whether I should release this or not.&lt;br /&gt;&lt;iframe width="560" height="349" src="http://www.youtube.com/embed/Sb6gXYIcZBM" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-8845477576525123127?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/8845477576525123127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/05/tahrir-square-ii-hes-back.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8845477576525123127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8845477576525123127'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/05/tahrir-square-ii-hes-back.html' title='Tahrir Square II: He&apos;s Back!'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/Sb6gXYIcZBM/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-5265992143005800442</id><published>2011-05-22T02:11:00.004+01:00</published><updated>2011-05-22T02:23:05.623+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='islam'/><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Best Hijabs Online</title><content type='html'>&lt;center&gt;&lt;a href="http://mh-couture.com/" target="_blank" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 500px;" src="http://mhcouture.webs.com//ffffffffffffffffffffffffffffffffffffffff.jpg" border="0" alt="" /&gt;http://mh-couture.com&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;Well my friend runs a Hijab fashion website called MH Couture. For some reason Facebook decided to ban all links to her site.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So being an awesome software engineer, I figured I'd try to circumvent their ban.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First, I first tried using a URL shortner (goo.gl, tinyurl), but that didn't work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I then tried to upload a webpage redirect using PHP by changing the header, but that didn't work.&lt;br /&gt;&lt;pre style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; &amp;lt;?php&lt;br /&gt;   header( "Location: http://mh-couture.com" );&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Finally, I used a javascript redirect, and that worked.&lt;br /&gt;&lt;pre style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt;window.location = "http://mh-couture.com"&lt;br /&gt;//--&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;kthanksbye&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-5265992143005800442?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/5265992143005800442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/05/best-hijabs-online.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5265992143005800442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5265992143005800442'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/05/best-hijabs-online.html' title='Best Hijabs Online'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-7041460173649556321</id><published>2011-05-17T23:46:00.009+01:00</published><updated>2011-05-18T01:22:35.954+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><title type='text'>Music Gym</title><content type='html'>When I work out at the gym, I need my music to motivate me.&lt;br /&gt;&lt;br /&gt;The first issue I have with the iPhone for gym music, is that whenever I want to change tracks, due to the touch screen, I'm forced to always pull the phone out of my pocket and touch the screen.&lt;br /&gt;&lt;br /&gt;The second issue is that, whenever I switch tracks, they always start from the beginning so to keep my psyche up, I need to manually fast forward into the chorus.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;To solve these issues, I put together..&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;MUSIC GYM!&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-_McCDl6HNhg/TdL8ZzJnbaI/AAAAAAAAARs/IvkS7XWY5vU/s1600/ScreenShot003.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 247px; height: 320px;" src="http://3.bp.blogspot.com/-_McCDl6HNhg/TdL8ZzJnbaI/AAAAAAAAARs/IvkS7XWY5vU/s320/ScreenShot003.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5607822006187158946" /&gt;&lt;/a&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" &gt;(prepare to notice the awesome 3D interface)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;When you go to the next track, it jumps straight into the chorus.&lt;br /&gt;When you tap the power button to put the phone to sleep, it allows you to skip tracks by double tapping the volume buttons.&lt;br /&gt;&lt;br /&gt;I use it at the gym now, and everyone thinks I'm on steroids because I've put on so much mass!&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;and that I'm on steroids&lt;/span&gt;&lt;span class="Apple-style-span"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small; "&gt;  (not really).&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-HBnpb3Rp2W4/TdL8aAGbpjI/AAAAAAAAAR0/RFWXt8Wk_qQ/s1600/ScreenShot002.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 306px;" src="http://4.bp.blogspot.com/-HBnpb3Rp2W4/TdL8aAGbpjI/AAAAAAAAAR0/RFWXt8Wk_qQ/s320/ScreenShot002.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5607822009663465010" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;br /&gt;&lt;a href="http://itunes.apple.com/us/app/music-gym/id435903595?mt=8&amp;amp;ls=1" target="_blank"&gt;http://itunes.apple.com/us/app/music-gym/id435903595&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://imgur.com/SFW8T" target="_blank"&gt;Bonus Rage Comic&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-7041460173649556321?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/7041460173649556321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/05/music-gym.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7041460173649556321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7041460173649556321'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/05/music-gym.html' title='Music Gym'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-_McCDl6HNhg/TdL8ZzJnbaI/AAAAAAAAARs/IvkS7XWY5vU/s72-c/ScreenShot003.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-662304714877788321</id><published>2011-04-22T00:24:00.004+01:00</published><updated>2011-04-22T14:40:16.885+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='islam'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='google maps'/><title type='text'>Mosque Finder for Females</title><content type='html'>Generally over here in the UK, mosques tend to cater for male practioners of the Islam faith. Last year &lt;a href="http://faith-matters.org/" target="_blank"&gt;Faith Matters&lt;/a&gt; took a look at the top 100 mosques in England that meet 5 core criteria that Muslim women wanted to see within mosques in the country.&lt;br /&gt;&lt;br /&gt;With the help of &lt;a href="http://faith-matters.org/" target="_blank"&gt;Faith Matters&lt;/a&gt;, I am happy to announce that the first iOS Mosque Finder app for Females is now available on the Apple App Store, completely free for a limited period.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-eixOgPphkR8/TbC72jhI3tI/AAAAAAAAADE/SE_qcGDAGEw/s1600/mzl.azemfjes.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="320" width="214" src="http://1.bp.blogspot.com/-eixOgPphkR8/TbC72jhI3tI/AAAAAAAAADE/SE_qcGDAGEw/s320/mzl.azemfjes.png" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/-BYqG11LVMK0/TbC73CxXuSI/AAAAAAAAADU/sDm9vkb3zAM/s1600/mzl.qomastnz.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="320" width="214" src="http://2.bp.blogspot.com/-BYqG11LVMK0/TbC73CxXuSI/AAAAAAAAADU/sDm9vkb3zAM/s320/mzl.qomastnz.png" /&gt;&lt;/a&gt;&lt;a href="http://1.bp.blogspot.com/-pzS2cBilmQM/TbC725xPpGI/AAAAAAAAADM/B63-3ty-nto/s1600/mzl.hcbwrrnn.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="320" width="214" src="http://1.bp.blogspot.com/-pzS2cBilmQM/TbC725xPpGI/AAAAAAAAADM/B63-3ty-nto/s320/mzl.hcbwrrnn.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Get it here&lt;br /&gt;&lt;a href="http://itunes.apple.com/app/women-in-islam-mosque-finder/id431515052" target="_blank"&gt;http://itunes.apple.com/app/women-in-islam-mosque-finder/id431515052&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-662304714877788321?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/662304714877788321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/04/mosque-finder-for-females.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/662304714877788321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/662304714877788321'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/04/mosque-finder-for-females.html' title='Mosque Finder for Females'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-eixOgPphkR8/TbC72jhI3tI/AAAAAAAAADE/SE_qcGDAGEw/s72-c/mzl.azemfjes.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-362014519178885347</id><published>2011-03-27T06:59:00.010+01:00</published><updated>2011-03-27T12:15:24.318+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='igrapher'/><category scheme='http://www.blogger.com/atom/ns#' term='egypt'/><title type='text'>Egyptian Stock Market - Before and After Mubarak</title><content type='html'>&lt;a href="http://twitpic.com/4dswh1" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 168px;" src="http://1.bp.blogspot.com/-q44cOfubUM8/TY8cGcPahqI/AAAAAAAAARQ/VtOHcbzL4v8/s1600/265048165.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5588716559575713442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;There's been a lot of panic lately about the Egyptian stock market. When it last opened it's value dropped by 10% as we can see in the chart below.&lt;br /&gt;&lt;br /&gt;&lt;iframe frameborder="1" height="350" marginheight="0" marginwidth="0" name="iGrapher" scrolling="no" src="http://igrapher.com/index_iframe.php?#iframe?1;intro?0;resizer?0;m?0:12;stock?ACGC.CA:EGX30;stock?EGTS.CA:EGX30;z?8;stock?SVCE.CA:EGX30;stock?UEGC.CA:EGX30;stock?TMGH.CA:EGX30;tmi?0;stock?DCRC.CA:EGX70;" width="600"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;However, if we look back a few years, you'll notice that latest drop in value is insignificant in comparison to it's overall devaluation under Mubarak's rule.&lt;/div&gt;&lt;br /&gt;&lt;iframe frameborder="1" height="350" marginheight="0" marginwidth="0" name="iGrapher" scrolling="no" src="http://igrapher.com/index_iframe.php?#iframe?1;intro?0;resizer?0;m?0:12;stock?ACGC.CA:EGX30;stock?EGTS.CA:EGX30;z?112;stock?SVCE.CA:EGX30;stock?UEGC.CA:EGX30;stock?TMGH.CA:EGX30;tmi?0;stock?DCRC.CA:EGX70;" width="600"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-362014519178885347?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/362014519178885347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/03/egyptian-stock-market-before-and-after.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/362014519178885347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/362014519178885347'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/03/egyptian-stock-market-before-and-after.html' title='Egyptian Stock Market - Before and After Mubarak'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-q44cOfubUM8/TY8cGcPahqI/AAAAAAAAARQ/VtOHcbzL4v8/s72-c/265048165.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-6834464149176124168</id><published>2011-03-26T04:38:00.005Z</published><updated>2011-03-26T09:44:06.689Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='softpoetry'/><title type='text'>SoftPoetry - Mission Statement</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;SoftPoetry.com is open.&lt;br /&gt;&lt;br /&gt;Our mission statement is simple.&lt;br /&gt;We write software. We write games. We write poetry.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-6834464149176124168?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/6834464149176124168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2011/03/softpoetrycom.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6834464149176124168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6834464149176124168'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2011/03/softpoetrycom.html' title='SoftPoetry - Mission Statement'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-3961432373362233772</id><published>2010-09-28T11:26:00.003+01:00</published><updated>2011-03-26T09:44:54.258Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='library'/><category scheme='http://www.blogger.com/atom/ns#' term='xcode'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='lipo'/><title type='text'>lipo Makes You Fat</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Ever had to link in an external library for your iPhone project?&lt;br /&gt;Did you receive a big headache having to switch between the simulator version and the iphone version of the library?&lt;br /&gt;&lt;br /&gt;Yes?&lt;br /&gt;&lt;br /&gt;Well, this is for you, run the lipo command, and it'll magically embed both versions into one FAT library.&lt;br /&gt;&lt;br /&gt;And fear not, the linker will only link in the required version. &lt;br /&gt;&lt;br /&gt;Example usage of lipo with "libSkinny"..&lt;br /&gt;&lt;pre style="background: url(&amp;quot;http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif&amp;quot;) repeat scroll 0% 0% rgb(240, 240, 240); border: 1px dashed rgb(204, 204, 204); color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; lipo -output build/libFatty.a -create build/Release-iphoneos/libSkinny.a build/Release-iphonesimulator/libSkinny.a  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;So it's official.. Lipo makes you fat. Well in the geek world anyway.&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Lipo"&gt;http://en.wikipedia.org/wiki/Lipo&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-3961432373362233772?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/3961432373362233772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/09/lipo-makes-you-fat.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3961432373362233772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3961432373362233772'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/09/lipo-makes-you-fat.html' title='lipo Makes You Fat'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-4222667402873844826</id><published>2010-09-01T11:36:00.004+01:00</published><updated>2011-03-26T09:54:33.824Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='prototypes'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='html5'/><category scheme='http://www.blogger.com/atom/ns#' term='games dev'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><title type='text'>HTML5 Canvas iPhone Level Editor</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So I've been working on and off on a Syndicate style birds eye view shooter, just as an excuse to mess around with AI again.&lt;br /&gt;&lt;br /&gt;When going on to creating the actual game map, usually I'd hard-coding everything (I see things easier in code). However, this time since I had an actual artist (non-programmer artist) create the base ground texture. Placing buildings to conform to an artists texture would be a pain, especially because maths and uniformity doesn't mesh with art. So yesterday I decided to quickly mock up a level editor using everyone's favourite new buzz word 'HTML5'.&lt;br /&gt;&lt;br /&gt;All it does is simply draw the ground texture on a webpage using the canvas tag, then allows you to draw rectangles over the image. These rectangles are then exported out as an xml file. The xml file is then read by the game, and buildings are placed in position and to proportion of the rectangles created.&lt;br /&gt;&lt;br /&gt;It's simple, it works, and since the level editor is web based, it should be relatively easy to release it alongside the game (if it ever gets done) for gamers to produce and play maps of their own.. I'll keep you updated.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_8_3RWQXfd-4/TH4v3N-SUcI/AAAAAAAAAA4/3G1Rpu215zU/s1600/Screen+shot+2010-09-01+at+11.45.17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_8_3RWQXfd-4/TH4v3N-SUcI/AAAAAAAAAA4/3G1Rpu215zU/s320/Screen+shot+2010-09-01+at+11.45.17.png" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_8_3RWQXfd-4/TH4v90pE59I/AAAAAAAAABA/pukK6dOJKSw/s1600/Screen+shot+2010-09-01+at+11.47.42.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_8_3RWQXfd-4/TH4v90pE59I/AAAAAAAAABA/pukK6dOJKSw/s320/Screen+shot+2010-09-01+at+11.47.42.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;1:  &amp;lt;xml&amp;gt; &lt;br /&gt;2:   &amp;lt;building x="0.5006934812760055" y="0.49791955617198336" w="0.13592233009708737" h="0.130374479889043"&amp;gt; &lt;br /&gt;3:   &amp;lt;/building&amp;gt; &lt;br /&gt;4:   &amp;lt;building x="0.2725381414701803" y="0.326629680998613" w="0.07350901525658807" h="0.0651872399445215"&amp;gt; &lt;br /&gt;5:   &amp;lt;/building&amp;gt; &lt;br /&gt;6:   &amp;lt;building x="0.32177531206657417" y="0.573509015256588" w="0.07489597780859916" h="0.07628294036061026"&amp;gt; &lt;br /&gt;7:   &amp;lt;/building&amp;gt; &lt;br /&gt;8:   &amp;lt;building x="0.6276005547850207" y="0.651872399445215" w="0.17614424410540916" h="0.022191400832177532"&amp;gt; &lt;br /&gt;9:   &amp;lt;/building&amp;gt; &lt;br /&gt;10:   &amp;lt;building x="0.651872399445215" y="0.4098474341192788" w="0.027739251040221916" h="0.14008321775312066"&amp;gt; &lt;br /&gt;11:   &amp;lt;/building&amp;gt; &lt;br /&gt;12:   &amp;lt;building x="0.7371705963938974" y="0.30374479889042993" w="0.04022191400832178" h="0.05547850208044383"&amp;gt; &lt;br /&gt;13:   &amp;lt;/building&amp;gt; &lt;br /&gt;14:   &amp;lt;building x="0.6900138696255201" y="0.04299583911234397" w="0.3536754507628294" h="0.030513176144244106"&amp;gt; &lt;br /&gt;15:   &amp;lt;/building&amp;gt; &lt;br /&gt;16:   &amp;lt;building x="0.3765603328710125" y="0.9251040221914009" w="0.05409153952843273" h="0.05547850208044383"&amp;gt; &lt;br /&gt;17:   &amp;lt;/building&amp;gt; &lt;br /&gt;18:   &amp;lt;building x="0.46393897364771153" y="0.9299583911234397" w="0.04299583911234397" h="0.03467406380027739"&amp;gt; &lt;br /&gt;19:   &amp;lt;/building&amp;gt; &lt;br /&gt;20:   &amp;lt;building x="0.17614424410540913" y="0.9112343966712898" w="0.04160887656033287" h="0.08599167822468794"&amp;gt; &lt;br /&gt;21:   &amp;lt;/building&amp;gt; &lt;br /&gt;22:   &amp;lt;building x="0.06726768377253814" y="0.782246879334258" w="0.04854368932038835" h="0.033287101248266296"&amp;gt; &lt;br /&gt;23:   &amp;lt;/building&amp;gt; &lt;br /&gt;24:   &amp;lt;building x="0.07420249653259361" y="0.8550624133148405" w="0.05409153952843273" h="0.0319001386962552"&amp;gt; &lt;br /&gt;25:   &amp;lt;/building&amp;gt; &lt;br /&gt;26:   &amp;lt;building x="0.06796116504854369" y="0.934119278779473" w="0.052704576976421634" h="0.04854368932038835"&amp;gt; &lt;br /&gt;27:   &amp;lt;/building&amp;gt; &lt;br /&gt;28:   &amp;lt;building x="0.07004160887656033" y="0.6761442441054092" w="0.04854368932038835" h="0.05409153952843273"&amp;gt; &lt;br /&gt;29:   &amp;lt;/building&amp;gt; &lt;br /&gt;30:   &amp;lt;building x="0.07420249653259361" y="0.5235783633841886" w="0.04854368932038835" h="0.04854368932038835"&amp;gt; &lt;br /&gt;31:   &amp;lt;/building&amp;gt; &lt;br /&gt;32:   &amp;lt;building x="0.12135922330097088" y="0.42718446601941745" w="0.04576976421636616" h="0.033287101248266296"&amp;gt; &lt;br /&gt;33:   &amp;lt;/building&amp;gt; &lt;br /&gt;34:   &amp;lt;building x="0.13106796116504854" y="0.07420249653259361" w="0.13730929264909847" h="0.05409153952843273"&amp;gt; &lt;br /&gt;35:   &amp;lt;/building&amp;gt; &lt;br /&gt;36:   &amp;lt;building x="0.9361997226074896" y="0.7281553398058253" w="0.05547850208044383" h="0.1636615811373093"&amp;gt; &lt;br /&gt;37:   &amp;lt;/building&amp;gt; &lt;br /&gt;38:  &amp;lt;/xml&amp;gt; &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;1:  void Scene03Game::loadBuildings(const char *filename) &lt;br /&gt;2:  { &lt;br /&gt;3:       const float height = 10.0f; &lt;br /&gt;4:        &lt;br /&gt;5:       // Parse xml config file &lt;br /&gt;6:       XMLDocument *xml = new XMLDocument(); &lt;br /&gt;7:       if( xml-&amp;gt;load( filename ) ) &lt;br /&gt;8:       { &lt;br /&gt;9:            // Get root node &lt;br /&gt;10:            XMLNode *xmlRoot = xml-&amp;gt;getRoot(); &lt;br /&gt;11:            if( xmlRoot != NULL ) &lt;br /&gt;12:            {      &lt;br /&gt;13:                 // Parse xml data &lt;br /&gt;14:                 xmlRoot = xmlRoot-&amp;gt;getRoot(); &lt;br /&gt;15:                 while( xmlRoot != NULL ) &lt;br /&gt;16:                 { &lt;br /&gt;17:                      if( xmlRoot-&amp;gt;tagIs( "building" ) ) &lt;br /&gt;18:                      { &lt;br /&gt;19:                           XMLNode *xmlBuilding = xmlRoot; &lt;br /&gt;20:                           { &lt;br /&gt;21:                                float x = xmlBuilding-&amp;gt;attributeFloat( "x", 0.0f ); &lt;br /&gt;22:                                float z = xmlBuilding-&amp;gt;attributeFloat( "y", 0.0f ); &lt;br /&gt;23:                                float width = xmlBuilding-&amp;gt;attributeFloat( "w", 0.0f ); &lt;br /&gt;24:                                float depth = xmlBuilding-&amp;gt;attributeFloat( "h", 0.0f ); &lt;br /&gt;25:                                 &lt;br /&gt;26:                                x *= ground-&amp;gt;collisionBounds.x * 2.0f; &lt;br /&gt;27:                                x -= ground-&amp;gt;collisionBounds.x; &lt;br /&gt;28:                                 &lt;br /&gt;29:                                z *= ground-&amp;gt;collisionBounds.z * 2.0f; &lt;br /&gt;30:                                z -= ground-&amp;gt;collisionBounds.z; &lt;br /&gt;31:                                 &lt;br /&gt;32:                                const float hWidth = width * ground-&amp;gt;collisionBounds.x; &lt;br /&gt;33:                                const float hDepth = depth * ground-&amp;gt;collisionBounds.z; &lt;br /&gt;34:                                 &lt;br /&gt;35:                                const float additionalHeight = (float)( rand() % 10 ); &lt;br /&gt;36:                                const int texture = rand() % 7; &lt;br /&gt;37:                                 &lt;br /&gt;38:                                ObjectBuilding *building = new ObjectBuilding( hWidth, hDepth, ( height + additionalHeight ) * 0.5f, texture_building1+texture ); &lt;br /&gt;39:                                building-&amp;gt;setPositionXZ( x, z ); &lt;br /&gt;40:                                building-&amp;gt;setScene( this ); &lt;br /&gt;41:                                gEngine-&amp;gt;collideables-&amp;gt;nodeNetwork-&amp;gt;addCollideable( building ); &lt;br /&gt;42:                           } &lt;br /&gt;43:                      } &lt;br /&gt;44:                      xmlRoot = xmlRoot-&amp;gt;next(); &lt;br /&gt;45:                 } &lt;br /&gt;46:            } &lt;br /&gt;47:       } &lt;br /&gt;48:       delete xml; &lt;br /&gt;49:  }  &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Note, if anyone else out there thinks they might have use for a web based editor, let me know and I can try extending it to suit more than my needs.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-4222667402873844826?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/4222667402873844826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/09/html5-canvas-iphone-level-editor.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4222667402873844826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4222667402873844826'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/09/html5-canvas-iphone-level-editor.html' title='HTML5 Canvas iPhone Level Editor'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_8_3RWQXfd-4/TH4v3N-SUcI/AAAAAAAAAA4/3G1Rpu215zU/s72-c/Screen+shot+2010-09-01+at+11.45.17.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-3223094908559681177</id><published>2010-06-16T04:55:00.007+01:00</published><updated>2011-03-26T09:47:37.089Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='igrapher'/><category scheme='http://www.blogger.com/atom/ns#' term='softpoetry'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><title type='text'>iGrapher 3D released</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Our first native iPad port of iGrapher has now been released on the App Store.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://itunes.apple.com/app/igrapher-3d/id374218741"&gt;&lt;img src="http://2.bp.blogspot.com/_z75fiuW5_aI/TBhMAOF_sBI/AAAAAAAAAP4/RGMp-YbvHjY/s320/mzl.tchzezgb.320x480-75.jpg" /&gt;&lt;br /&gt;http://itunes.apple.com/app/igrapher-3d/id374218741&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Expect lots of more features coming in the next versions.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-3223094908559681177?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/3223094908559681177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/06/igrapher-3d-released.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3223094908559681177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3223094908559681177'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/06/igrapher-3d-released.html' title='iGrapher 3D released'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_z75fiuW5_aI/TBhMAOF_sBI/AAAAAAAAAP4/RGMp-YbvHjY/s72-c/mzl.tchzezgb.320x480-75.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-1080040269476053998</id><published>2010-05-24T02:51:00.003+01:00</published><updated>2011-03-26T09:48:18.346Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='igrapher'/><category scheme='http://www.blogger.com/atom/ns#' term='softpoetry'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><title type='text'>iGrapher 3D submitted</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;a href="http://twitpic.com/1qif5q" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" target="_blank"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5474649614752163810" src="http://1.bp.blogspot.com/_z75fiuW5_aI/S_nc0ZUIJ-I/AAAAAAAAAPw/woSSt81rP5U/s320/iTunes.png" style="cursor: hand; cursor: pointer; display: block; height: 320px; margin: 0px auto 10px; text-align: center; width: 320px;" /&gt;&lt;/a&gt;&lt;br /&gt;After a week of dev, the first release of iGrapher 3D has just been submitted.&lt;br /&gt;&lt;br /&gt;It's been developed to work on the iPad and iPhone 3GS. It does run on the older iPhones, but not smooth enough for my liking.&lt;br /&gt;&lt;br /&gt;The first release will feature panning, rotating, zooming, raining (yes there's rain), and price scanning through the ftse 100 and dow jones indices in glorious 3D.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-1080040269476053998?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/1080040269476053998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/05/igrapher-3d-submitted.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1080040269476053998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1080040269476053998'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/05/igrapher-3d-submitted.html' title='iGrapher 3D submitted'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_z75fiuW5_aI/S_nc0ZUIJ-I/AAAAAAAAAPw/woSSt81rP5U/s72-c/iTunes.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-5260153650408269639</id><published>2010-05-18T00:47:00.004+01:00</published><updated>2011-03-26T09:51:16.474Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='igrapher'/><category scheme='http://www.blogger.com/atom/ns#' term='prototypes'/><category scheme='http://www.blogger.com/atom/ns#' term='softpoetry'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><title type='text'>iGrapher 3D</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Here's a small peak at iGrapher ported for the iPad.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;object height="385" width="640"&gt;&lt;param name="movie" value="http://www.youtube.com/v/57c9WCpgLKg&amp;hl=en_GB&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/57c9WCpgLKg&amp;hl=en_GB&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/center&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-5260153650408269639?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/5260153650408269639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/05/igrapher-3d.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5260153650408269639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5260153650408269639'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/05/igrapher-3d.html' title='iGrapher 3D'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-1597718120123986219</id><published>2010-03-15T01:25:00.002Z</published><updated>2011-03-26T09:45:12.819Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='openal'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='uiwebview'/><category scheme='http://www.blogger.com/atom/ns#' term='youtube'/><title type='text'>How to play YouTube videos in your iPhone app</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So I was trying to launch a YouTube video from my game, without the game switching to the YouTube app. To do this, I ran into a few issues.&lt;br /&gt;&lt;br /&gt;Here I'll describe how to set up the playing of a YouTube video and how to tackle the issues you will encounter.&lt;br /&gt;&lt;br /&gt;So first you must create a UIWebView and add it to your main view.&lt;br /&gt;In the following I create a webview pointing to http://technolojia.com/NahBruv/trailer.htm where I have embedding the YouTube clip I want to play, I set it hidden because I'll later want to launch the video full screen.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;      htmlView = [[UIWebView alloc] initWithFrame:CGRectMake( 55.0f, 105.0f, 369.0f, 178.0f) ];  &lt;br /&gt;[htmlView setBackgroundColor:[UIColor blackColor]];  &lt;br /&gt;htmlView.hidden = YES;  &lt;br /&gt;htmlView.delegate = self;  &lt;br /&gt;[self addSubview:htmlView];  &lt;br /&gt;[htmlView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://technolojia.com/NahBruv/trailer.htm"]]];  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So now in the background the webview starts seeking the website http://technolojia.com/NahBruv/trailer.htm&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; &amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&amp;gt;  &lt;br /&gt;&amp;lt;html&amp;gt;  &lt;br /&gt;&amp;lt;head&amp;gt;  &lt;br /&gt;&amp;lt;title&amp;gt;Trailer Page&amp;lt;/title&amp;gt;  &lt;br /&gt;&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&amp;gt;  &lt;br /&gt;&amp;lt;/head&amp;gt;  &lt;br /&gt;&amp;lt;object width="369" height="178"&amp;gt;  &lt;br /&gt;&amp;lt;param name="movie" value="http://www.youtube.com/v/Aq4wI89cUa4&amp;amp;autoplay=1&amp;amp;fmt=18"&amp;gt;  &lt;br /&gt;&amp;lt;/param&amp;gt;&amp;lt;param name="allowFullScreen" value="true"&amp;gt;  &lt;br /&gt;&amp;lt;/param&amp;gt;&amp;lt;param name="allowscriptaccess" value="always"&amp;gt;&amp;lt;param name="wmode" value="transparent" /&amp;gt;  &lt;br /&gt;&amp;lt;/param&amp;gt;  &lt;br /&gt;&amp;lt;embed src="http://www.youtube.com/v/Aq4wI89cUa4&amp;amp;autoplay=1&amp;amp;fmt=18" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="369" height="178"&amp;gt;  &lt;br /&gt;&amp;lt;/embed&amp;gt;  &lt;br /&gt;&amp;lt;/object&amp;gt;  &lt;br /&gt;&amp;lt;/html&amp;gt;  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once it's loaded it'll call the delegate function which you music implement in your class. Notice I set htmlView.delgate = self. I do this because I want to launch the video once the page is loaded, because by default YouTube video's need to have the play button clicked before they launch in the MPMoviePlayerController object.&lt;br /&gt;&lt;br /&gt;So here I scan through all the buttons in the webview and select the first button found using the sendActionsForControlEvents function.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; UIButton* findButtonInView(UIView* view)  &lt;br /&gt;{  &lt;br /&gt;UIButton *button = nil;  &lt;br /&gt;if( [view isMemberOfClass:[UIButton class]] )  &lt;br /&gt;{  &lt;br /&gt;return (UIButton*)view;  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;if( view.subviews &amp;amp;&amp;amp; [view.subviews count] &amp;gt; 0 )  &lt;br /&gt;{  &lt;br /&gt;for( UIView *subview in view.subviews )  &lt;br /&gt;{  &lt;br /&gt;button = findButtonInView( subview );  &lt;br /&gt;if( button )   &lt;br /&gt;{  &lt;br /&gt;return button;  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;return button;  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;-(void)webViewDidFinishLoad:(UIWebView*)webView  &lt;br /&gt;{  &lt;br /&gt;UIButton *button = findButtonInView( webView );  &lt;br /&gt;if( button != nil )  &lt;br /&gt;{  &lt;br /&gt;[button sendActionsForControlEvents:UIControlEventTouchUpInside];  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Great so far huh? But on return if you're using OpenAL, the sound no longer works. Eek. So what you have to do is, before launching the video you must make sure you call AudioSessionSetActive( NO ) and then AudioSessionSetActive( YES ) once the video has finished. I also found I had to destroy and recreate my OpenAL context and samples loaded, but I haven't looked too much into it, so if you find a way to reuse your OpenAL context and device, let me know.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; if( stoppingAudio )  &lt;br /&gt;{  &lt;br /&gt;[audioManager destroy];  &lt;br /&gt;AudioSessionSetActive( NO );  &lt;br /&gt;}  &lt;br /&gt;else if( restartingAudio )  &lt;br /&gt;{  &lt;br /&gt;AudioSessionSetActive( YES );  &lt;br /&gt;[audioManager load:YES];  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's it, you now can launch a YouTube video fullscreen in your app, without losing audio or having the YouTube application take over. Enjoy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;embed allowfullscreen="true" allowscriptaccess="always" height="178" src="http://www.youtube.com/v/Aq4wI89cUa4&amp;amp;fmt=18" type="application/x-shockwave-flash" width="369"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;/center&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-1597718120123986219?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/1597718120123986219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/03/how-to-play-youtube-videos-in-your.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1597718120123986219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1597718120123986219'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/03/how-to-play-youtube-videos-in-your.html' title='How to play YouTube videos in your iPhone app'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-1388281522017814662</id><published>2010-02-16T05:57:00.002Z</published><updated>2011-03-26T09:48:44.863Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='stock market hero'/><category scheme='http://www.blogger.com/atom/ns#' term='softpoetry'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><title type='text'>Stock Market Hero submitted</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Just managed to submit make my first submission to the app store. Getting a distribution profile was a pain.. I'll post more details after I've got some sleep..&lt;br /&gt;&lt;br /&gt;&lt;a href="http://twitpic.com/13jdui" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" target="_blank"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5438854061977432354" src="http://2.bp.blogspot.com/_z75fiuW5_aI/S3qw8_1a8SI/AAAAAAAAAPY/IZwvmef0HAQ/s320/66409434.png" style="cursor: hand; cursor: pointer; display: block; height: 320px; margin: 0px auto 10px; text-align: center; width: 320px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitpic.com/13jdav" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" target="_blank"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5438854070006423234" src="http://1.bp.blogspot.com/_z75fiuW5_aI/S3qw9dvrnsI/AAAAAAAAAPg/sPCbGiN81zc/s320/66408727.png" style="cursor: hand; cursor: pointer; display: block; height: 163px; margin: 0px auto 10px; text-align: center; width: 320px;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-1388281522017814662?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/1388281522017814662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/02/stock-market-hero-submitted.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1388281522017814662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1388281522017814662'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/02/stock-market-hero-submitted.html' title='Stock Market Hero submitted'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_z75fiuW5_aI/S3qw8_1a8SI/AAAAAAAAAPY/IZwvmef0HAQ/s72-c/66409434.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-892528053993122451</id><published>2010-02-09T19:51:00.005Z</published><updated>2011-03-26T09:47:20.409Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='igrapher'/><title type='text'>Graph Normalization</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Just implemented a new feature called Graph Normalization as suggested by Jeff from &lt;a href="http://www.forex-fundamental-analysis.com/live_market_visualisation/06/" target="_blank"&gt;Forex Fundamental Analysis&lt;/a&gt;. The problem previously was when you chart stocks with extreme differences in price levels, it's impossible to visualize the graph shapes together.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_z75fiuW5_aI/S3G9Yu1dbQI/AAAAAAAAAO4/cs0PkomlV48/s1600-h/ScreenShot001.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5436334457799666946" src="http://3.bp.blogspot.com/_z75fiuW5_aI/S3G9Yu1dbQI/AAAAAAAAAO4/cs0PkomlV48/s320/ScreenShot001.png" style="cursor: hand; cursor: pointer; display: block; height: 306px; margin: 0px auto 10px; text-align: center; width: 320px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But now with the Graph Normalization feature, you can normalize the graphs to see the pattern by clicking on the graph you wish to normalize the rest by..&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_z75fiuW5_aI/S3G9Y_H4PMI/AAAAAAAAAPA/nM61OzP6w_4/s1600-h/ScreenShot002.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5436334462171888834" src="http://3.bp.blogspot.com/_z75fiuW5_aI/S3G9Y_H4PMI/AAAAAAAAAPA/nM61OzP6w_4/s320/ScreenShot002.png" style="cursor: hand; cursor: pointer; display: block; height: 75px; margin: 0px auto 10px; text-align: center; width: 320px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then selecting Normalize Graph..&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_z75fiuW5_aI/S3G9ZSwMF_I/AAAAAAAAAPI/XE0yDCX6ZS4/s1600-h/ScreenShot003.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5436334467441235954" src="http://1.bp.blogspot.com/_z75fiuW5_aI/S3G9ZSwMF_I/AAAAAAAAAPI/XE0yDCX6ZS4/s320/ScreenShot003.png" style="cursor: hand; cursor: pointer; display: block; height: 197px; margin: 0px auto 10px; text-align: center; width: 288px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now all the graphs will be normalized to the chosen scale..&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_z75fiuW5_aI/S3G9ZZd_NII/AAAAAAAAAPQ/mKoDJHkNvvQ/s1600-h/ScreenShot004.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5436334469243942018" src="http://4.bp.blogspot.com/_z75fiuW5_aI/S3G9ZZd_NII/AAAAAAAAAPQ/mKoDJHkNvvQ/s320/ScreenShot004.png" style="cursor: hand; cursor: pointer; display: block; height: 303px; margin: 0px auto 10px; text-align: center; width: 320px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can denormalize the charts using the same option.&lt;br /&gt;&lt;br /&gt;If anyone has any requests/suggestions, feel free to drop me a line.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-892528053993122451?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/892528053993122451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/02/graph-normalization.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/892528053993122451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/892528053993122451'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/02/graph-normalization.html' title='Graph Normalization'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_z75fiuW5_aI/S3G9Yu1dbQI/AAAAAAAAAO4/cs0PkomlV48/s72-c/ScreenShot001.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-8420060629864080388</id><published>2010-02-09T08:21:00.002Z</published><updated>2011-03-26T09:54:38.451Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='fonts'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><category scheme='http://www.blogger.com/atom/ns#' term='games dev'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><title type='text'>Font pages</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;I recently switched from rendering texture strings to font pages. The difference between the two is for texture strings you'd render the string into a bitmap and assign the image to an openGL handle. For a font page, you'd create all the characters of the font required and then when rendering a string, you'd fetch the characters required individually from the created page to render one by one.&lt;br /&gt;&lt;br /&gt;The reason for switching was to display a more dynamic text such as an OSD counter. With the old system I'd have to have to constantly create and release different images representing the numbers required, which would be impractical.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://twitpic.com/1271x1" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5436160338217003122" src="http://3.bp.blogspot.com/_z75fiuW5_aI/S3EfBo196HI/AAAAAAAAAOs/58CTap5yuO0/s320/Picture+1.png" style="cursor: hand; cursor: pointer; display: block; height: 212px; margin: 0px auto 10px; text-align: center; width: 320px;" target="_blank" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="340" width="560"&gt;&lt;param name="movie" value="http://www.youtube.com/v/H27IsYAMWnw&amp;hl=en_GB&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/H27IsYAMWnw&amp;hl=en_GB&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;So here's how rendering text using a font page works.&lt;br /&gt;&lt;br /&gt;First we initialize our class, where we create a bitmap with all the characters from the font required, and paste them one by one onto the page, incrementing the width and height as we paste along..&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; -(id)init  &lt;br /&gt;{  &lt;br /&gt;if( self = [super init] )  &lt;br /&gt;{  &lt;br /&gt;// Initialise our texture page  &lt;br /&gt;UIFont *font = [UIFont fontWithName:@"Trebuchet MS" size:32];  &lt;br /&gt;width = 512;  &lt;br /&gt;height = 256;  &lt;br /&gt;widthAspect = ( width * gView-&amp;gt;actualScreenSizeMultiple.width );  &lt;br /&gt;heightAspect = ( height * gView-&amp;gt;actualScreenSizeMultiple.height );  &lt;br /&gt;const CGSize textureSizeMultiple = CGSizeMake( 1.0f / width, 1.0f / height );&lt;br /&gt;&lt;br /&gt;CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();  &lt;br /&gt;void *data = calloc( height, width );  &lt;br /&gt;CGContextRef context = CGBitmapContextCreate( data, width, height, 8, width, colorSpace, kCGImageAlphaNone );  &lt;br /&gt;CGColorSpaceRelease( colorSpace );  &lt;br /&gt;CGContextSetGrayFillColor( context, 1.0f, 1.0f );  &lt;br /&gt;UIGraphicsPushContext( context );  &lt;br /&gt;&lt;br /&gt;// Create our characters  &lt;br /&gt;float x = 0.0f, y = 0.0f;  &lt;br /&gt;float maxY = 0.0f;  &lt;br /&gt;for( uint i=0; i&amp;lt;128; ++i )  &lt;br /&gt;{  &lt;br /&gt;NSString *string = [[NSString alloc] initWithString:@"£"];  &lt;br /&gt;letters[i].stringSize = [string sizeWithFont:font];  &lt;br /&gt;float endX = x + letters[i].stringSize.width + 1.0f;  &lt;br /&gt;if( endX &amp;gt; 512.0f )  &lt;br /&gt;{  &lt;br /&gt;x = 0.0f;  &lt;br /&gt;y += maxY + 1.0f;  &lt;br /&gt;maxY = letters[i].stringSize.height;  &lt;br /&gt;endX = letters[i].stringSize.width + 1.0f;  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;// Check if we've reached the end of the page&lt;br /&gt;if( letters[i].stringSize.height &amp;gt; maxY )  &lt;br /&gt;{  &lt;br /&gt;maxY = letters[i].stringSize.height;  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;letters[i].start.x = x;  &lt;br /&gt;letters[i].start.y = y;  &lt;br /&gt;[string drawInRect:CGRectMake( x, y, letters[i].stringSize.width, letters[i].stringSize.height) withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft ];  &lt;br /&gt;x = endX;  &lt;br /&gt;// Normalize  &lt;br /&gt;letters[i].stringSize.width *= textureSizeMultiple.width;  &lt;br /&gt;letters[i].stringSize.height *= textureSizeMultiple.height;  &lt;br /&gt;letters[i].start.x *= textureSizeMultiple.width;  &lt;br /&gt;letters[i].start.y = 1.0f - ( letters[i].start.y * textureSizeMultiple.height );  &lt;br /&gt;letters[i].end.x = letters[i].start.x + letters[i].stringSize.width;  &lt;br /&gt;letters[i].end.y = letters[i].start.y - letters[i].stringSize.height;  &lt;br /&gt;[string release];  &lt;br /&gt;}  &lt;br /&gt;assert( maxY + y &amp;lt; height ); &lt;br /&gt;&lt;br /&gt;// Finish our texture page  &lt;br /&gt;UIGraphicsPopContext();  &lt;br /&gt;glGenTextures( 1, &amp;amp;name );  &lt;br /&gt;BindTexture( name );  &lt;br /&gt;glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );  &lt;br /&gt;glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data );  &lt;br /&gt;CGContextRelease( context );  &lt;br /&gt;free( data );  &lt;br /&gt;BindTexture( 0 );  &lt;br /&gt;}  &lt;br /&gt;return self;  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now to render any given string, we just look up the letters one by one and render each one with their stored sizes..&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; -(void)renderText:(const char*)string length:(const uint)length x:(const float)x y:(const float)y centered:(const BOOL)centered size:(const float)size  &lt;br /&gt;{    &lt;br /&gt;BindTexture( name );  &lt;br /&gt;&lt;br /&gt;// Find out our width so we can center the text  &lt;br /&gt;float totalWidth = 0.0f, maxHeight = 0.0f;  &lt;br /&gt;float widths[length], heights[length];  &lt;br /&gt;for( uint i=0; i&amp;lt;length; ++i )  &lt;br /&gt;{  &lt;br /&gt;const Letters *letter = [self getLetter:string[i]];  &lt;br /&gt;if( letter != nil )  &lt;br /&gt;{  &lt;br /&gt;widths[i] = widthAspect * letter-&amp;gt;stringSize.width * size;  &lt;br /&gt;totalWidth += widths[i];  &lt;br /&gt;heights[i] = heightAspect * letter-&amp;gt;stringSize.height * size;  &lt;br /&gt;maxHeight = MAX( maxHeight, heights[i] );  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;CGPoint start = CGPointMake( x, y );  &lt;br /&gt;if( centered )  &lt;br /&gt;{  &lt;br /&gt;start.x -= totalWidth * 0.5f;  &lt;br /&gt;start.y -= maxHeight * 0.5f;  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;CGPoint currentStart = start;  &lt;br /&gt;for( uint i=0; i&amp;lt;length; ++i )  &lt;br /&gt;{  &lt;br /&gt;const Letters *letter = [self getLetter:string[i]];  &lt;br /&gt;if( letter != nil )  &lt;br /&gt;{  &lt;br /&gt;// Calculate end point  &lt;br /&gt;CGPoint orientatedStart = currentStart;  &lt;br /&gt;CGPoint end;  &lt;br /&gt;end.x = orientatedStart.x + widths[i];  &lt;br /&gt;end.y = orientatedStart.y + heights[i];  &lt;br /&gt;&lt;br /&gt;const GLfloat texCoords[] =   &lt;br /&gt;{  &lt;br /&gt;letter-&amp;gt;start.x, letter-&amp;gt;start.y,  &lt;br /&gt;letter-&amp;gt;end.x, letter-&amp;gt;start.y,  &lt;br /&gt;letter-&amp;gt;start.x, letter-&amp;gt;end.y,  &lt;br /&gt;letter-&amp;gt;end.x, letter-&amp;gt;end.y  &lt;br /&gt;};  &lt;br /&gt;glTexCoordPointer( 2, GL_FLOAT, 0, texCoords );  &lt;br /&gt;RenderSquare( orientatedStart, end );  &lt;br /&gt;currentStart.x += widths[i];  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;BindTexture( 0 );  &lt;br /&gt;DefaultTexCoords();  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Any issues, let me know.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-8420060629864080388?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/8420060629864080388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/02/font-pages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8420060629864080388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8420060629864080388'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/02/font-pages.html' title='Font pages'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_z75fiuW5_aI/S3EfBo196HI/AAAAAAAAAOs/58CTap5yuO0/s72-c/Picture+1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-8001971298400902198</id><published>2010-02-05T22:08:00.002Z</published><updated>2011-03-26T09:51:56.089Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='prototypes'/><category scheme='http://www.blogger.com/atom/ns#' term='stock market hero'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><title type='text'>3D Level Generation</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So, I've been experimenting with generating levels based off actual stock market history data.&lt;br /&gt;&lt;br /&gt;Here's a little preview of the result..&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/uXV9PLg0f0c&amp;hl=en_GB&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/uXV9PLg0f0c&amp;hl=en_GB&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-8001971298400902198?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/8001971298400902198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/02/3d-level-generation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8001971298400902198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8001971298400902198'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/02/3d-level-generation.html' title='3D Level Generation'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-4000111678091576206</id><published>2010-02-05T22:06:00.006Z</published><updated>2011-03-26T09:53:06.607Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='prototypes'/><category scheme='http://www.blogger.com/atom/ns#' term='stock market hero'/><category scheme='http://www.blogger.com/atom/ns#' term='ios'/><title type='text'>iGrapher 3D Level Generation</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;So I've been working on a 3D engine for the iPhone and decided to quickly throw together a level generated from non-other than stock market history.&lt;br /&gt;&lt;br /&gt;Check it out..&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/uXV9PLg0f0c&amp;hl=en_GB&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/uXV9PLg0f0c&amp;hl=en_GB&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-4000111678091576206?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/4000111678091576206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/02/igrapher-3d-level.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4000111678091576206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4000111678091576206'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/02/igrapher-3d-level.html' title='iGrapher 3D Level Generation'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-6283847218862380144</id><published>2010-01-20T03:46:00.001Z</published><updated>2011-03-26T09:50:29.538Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='prototypes'/><title type='text'>I didn't get dumped..</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Just managed to re-use my male character model to create a female. It's still work in progress, but it was enough to inspired me to put together this quick concept cover art.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://twitpic.com/yvx7v" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" target="_blank"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5428663685901560658" src="http://2.bp.blogspot.com/_z75fiuW5_aI/S1Z83Cs5q1I/AAAAAAAAAJY/snJvEctPuIQ/s320/Space+Aliens.png" style="cursor: hand; cursor: pointer; display: block; height: 292px; margin: 0px auto 10px; text-align: center; width: 320px;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-6283847218862380144?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/6283847218862380144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/01/i-didn-get-dumped.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6283847218862380144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6283847218862380144'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/01/i-didn-get-dumped.html' title='I didn&amp;#39;t get dumped..'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_z75fiuW5_aI/S1Z83Cs5q1I/AAAAAAAAAJY/snJvEctPuIQ/s72-c/Space+Aliens.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-177947278002650794</id><published>2010-01-18T09:22:00.001Z</published><updated>2011-03-26T09:53:49.766Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='games dev'/><title type='text'>Octrees - Code and walkthrough</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Octrees are a data structure to represent spartially dividing up a scene. The way they work is to divide up a scene into eight leafs, with each leaf further dividing up if they contained more objects than the set threashold.&lt;br /&gt;&lt;br /&gt;You could then use this divided up scene for optimisations. Such as to only process rendering for the objects in the visible octrees, or to only process collisions for the objects in the same octree as the current object.&lt;br /&gt;&lt;br /&gt;Here's a video of the octrees in action, notice how when a leaf becomes dense, it breaks down into a further eight leafs.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/sQYPxlp2tqs&amp;hl=en_GB&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/sQYPxlp2tqs&amp;hl=en_GB&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;So let's start.&lt;br /&gt;&lt;br /&gt;First we create our octree structure. With each octree will containing a pointer to it's parent tree, it's eight leafs, a set of objects and it's world position.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; enum OctreeLeafs  &lt;br /&gt;{  &lt;br /&gt;leaf_bottom_front_left,  &lt;br /&gt;leaf_bottom_front_right,  &lt;br /&gt;leaf_bottom_back_left,  &lt;br /&gt;leaf_bottom_back_right,  &lt;br /&gt;&lt;br /&gt;leaf_top_front_left,  &lt;br /&gt;leaf_top_front_right,  &lt;br /&gt;leaf_top_back_left,  &lt;br /&gt;leaf_top_back_right,  &lt;br /&gt;};  &lt;br /&gt;&lt;br /&gt;struct Octree  &lt;br /&gt;{  &lt;br /&gt;Octree *parent;  &lt;br /&gt;Octree **leafs;  &lt;br /&gt;ObjectCollideable *objects[MAX_TREE_OBJECTS];  &lt;br /&gt;uint numberOfObjects;  &lt;br /&gt;&lt;br /&gt;float hSize;  &lt;br /&gt;Vector3 min, max;  &lt;br /&gt;};  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We can then create the octree with.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; void OctreeNew(Octree **tree, Octree *parent, const Vector3 position, const float size)  &lt;br /&gt;{  &lt;br /&gt;*tree = malloc( sizeof( Octree ) );  &lt;br /&gt;(*tree)-&amp;gt;parent = parent;  &lt;br /&gt;(*tree)-&amp;gt;leafs = nil;  &lt;br /&gt;(*tree)-&amp;gt;numberOfObjects = 0;  &lt;br /&gt;&lt;br /&gt;(*tree)-&amp;gt;hSize = size * 0.5f;  &lt;br /&gt;(*tree)-&amp;gt;min = position;  &lt;br /&gt;(*tree)-&amp;gt;max = position;  &lt;br /&gt;Vector3AddFloat( &amp;amp;(*tree)-&amp;gt;min, -(*tree)-&amp;gt;hSize );  &lt;br /&gt;Vector3AddFloat( &amp;amp;(*tree)-&amp;gt;max, (*tree)-&amp;gt;hSize );  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now we'd need to handle adding an object to the tree, this is done by use of recursive function calls, that drill down into the leaf nodes to add the object to all the leafs it resides in. Once it's found a leaf if we have space for the object we add it into it's object list, if we don't have space we'll need to split the tree down to a further eight leafs and re-attempt adding the object.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; void OctreeAddObject(Octree *tree, ObjectCollideable *collideable)  &lt;br /&gt;{   &lt;br /&gt;// Ensure the object is within the octree's limits  &lt;br /&gt;if( tree-&amp;gt;parent == nil )  &lt;br /&gt;{  &lt;br /&gt;UpdateCollisions( collideable );  &lt;br /&gt;Vector3 *objectMin = &amp;amp;collideable-&amp;gt;min;  &lt;br /&gt;Vector3 *objectMax = &amp;amp;collideable-&amp;gt;max;  &lt;br /&gt;if( objectMax-&amp;gt;x &amp;lt; tree-&amp;gt;min.x ||   &lt;br /&gt;objectMax-&amp;gt;y &amp;lt; tree-&amp;gt;min.y ||   &lt;br /&gt;objectMax-&amp;gt;z &amp;lt; tree-&amp;gt;min.z ||   &lt;br /&gt;objectMin-&amp;gt;x &amp;gt; tree-&amp;gt;max.x ||   &lt;br /&gt;objectMin-&amp;gt;y &amp;gt; tree-&amp;gt;max.y ||   &lt;br /&gt;objectMin-&amp;gt;z &amp;gt; tree-&amp;gt;max.z )  &lt;br /&gt;{  &lt;br /&gt;return;  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;// Insert in an approperate leaf node  &lt;br /&gt;if( tree-&amp;gt;leafs != nil )  &lt;br /&gt;{  &lt;br /&gt;UpdateCollisions( collideable );  &lt;br /&gt;&lt;br /&gt;for( uint i=0; i&amp;lt;8; ++i )  &lt;br /&gt;{  &lt;br /&gt;Octree *leaf = tree-&amp;gt;leafs[i];  &lt;br /&gt;if( OctreeIsInLeaf( leaf, &amp;amp;collideable-&amp;gt;min, &amp;amp;collideable-&amp;gt;max ) )  &lt;br /&gt;{  &lt;br /&gt;OctreeAddObject( leaf, collideable );  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;// Unless we don't have any  &lt;br /&gt;else if( tree-&amp;gt;numberOfObjects &amp;lt; MAX_TREE_OBJECTS )  &lt;br /&gt;{  &lt;br /&gt;tree-&amp;gt;objects[tree-&amp;gt;numberOfObjects++] = collideable;  &lt;br /&gt;assert( collideable-&amp;gt;numberOfOctrees &amp;lt; MAX_OBJECT_TREES );  &lt;br /&gt;collideable-&amp;gt;octrees[collideable-&amp;gt;numberOfOctrees++] = tree;  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;// If we have too many objects split the octree  &lt;br /&gt;else  &lt;br /&gt;{  &lt;br /&gt;OctreeSplit( tree );  &lt;br /&gt;&lt;br /&gt;// Try again  &lt;br /&gt;OctreeAddObject( tree, collideable );  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;To check if the object resides in a leaf's space we simply use our min max vectors which we're set in OctreeNew.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; BOOL OctreeIsInLeaf(Octree *leaf, Vector3 *targetMin, Vector3 *targetMax)  &lt;br /&gt;{  &lt;br /&gt;Vector3 *sourceMin = &amp;amp;leaf-&amp;gt;min;  &lt;br /&gt;Vector3 *sourceMax = &amp;amp;leaf-&amp;gt;max;  &lt;br /&gt;&lt;br /&gt;if( sourceMax-&amp;gt;y &amp;gt; targetMin-&amp;gt;y &amp;amp;&amp;amp; sourceMin-&amp;gt;y &amp;lt; targetMax-&amp;gt;y )  &lt;br /&gt;{  &lt;br /&gt;if( sourceMax-&amp;gt;x &amp;gt; targetMin-&amp;gt;x &amp;amp;&amp;amp; sourceMin-&amp;gt;x &amp;lt; targetMax-&amp;gt;x )  &lt;br /&gt;{  &lt;br /&gt;if( sourceMax-&amp;gt;z &amp;gt; targetMin-&amp;gt;z &amp;amp;&amp;amp; sourceMin-&amp;gt;z &amp;lt; targetMax-&amp;gt;z )  &lt;br /&gt;{  &lt;br /&gt;return YES;  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;return NO;  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now comes the fun part, splitting our octree into a further eight octrees.&lt;br /&gt;To do so, we first create the eight leaf nodes from our parent's min max vectors and hSize variables.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; void OctreeSplitTopLeafs(Octree *tree, const uint index, Vector3 position)  &lt;br /&gt;{  &lt;br /&gt;position.y += tree-&amp;gt;hSize;  &lt;br /&gt;Octree **leaf = &amp;amp;( tree-&amp;gt;leafs[index+4] );  &lt;br /&gt;OctreeNew( leaf, tree, position, tree-&amp;gt;hSize );  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void OctreeSplit(Octree *tree)  &lt;br /&gt;{  &lt;br /&gt;assert( tree-&amp;gt;leafs == nil );  &lt;br /&gt;tree-&amp;gt;leafs = malloc( sizeof( Octree ) * 8 );  &lt;br /&gt;&lt;br /&gt;// Create our leaf nodes  &lt;br /&gt;uint index = leaf_bottom_front_left;  &lt;br /&gt;Vector3 position = tree-&amp;gt;min;  &lt;br /&gt;Vector3AddFloat( &amp;amp;position, tree-&amp;gt;hSize * 0.5f );  &lt;br /&gt;Octree **leaf = &amp;amp;( tree-&amp;gt;leafs[index] );  &lt;br /&gt;OctreeNew( leaf, tree, position, tree-&amp;gt;hSize );  &lt;br /&gt;OctreeSplitTopLeafs( tree, index, position );  &lt;br /&gt;&lt;br /&gt;index = leaf_bottom_front_right;  &lt;br /&gt;position.x += tree-&amp;gt;hSize;  &lt;br /&gt;leaf = &amp;amp;( tree-&amp;gt;leafs[index] );  &lt;br /&gt;OctreeNew( leaf, tree, position, tree-&amp;gt;hSize );  &lt;br /&gt;OctreeSplitTopLeafs( tree, index, position );  &lt;br /&gt;&lt;br /&gt;index = leaf_bottom_back_right;  &lt;br /&gt;position.z += tree-&amp;gt;hSize;  &lt;br /&gt;leaf = &amp;amp;( tree-&amp;gt;leafs[index] );  &lt;br /&gt;OctreeNew( leaf, tree, position, tree-&amp;gt;hSize );  &lt;br /&gt;OctreeSplitTopLeafs( tree, index, position );  &lt;br /&gt;&lt;br /&gt;index = leaf_bottom_back_left;  &lt;br /&gt;position.x -= tree-&amp;gt;hSize;  &lt;br /&gt;leaf = &amp;amp;( tree-&amp;gt;leafs[index] );  &lt;br /&gt;OctreeNew( leaf, tree, position, tree-&amp;gt;hSize );  &lt;br /&gt;OctreeSplitTopLeafs( tree, index, position );  &lt;br /&gt;...  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;We then parse through the current leaf's objects, remove them from the object list and re-add them into the appropriate new leafs we've just created.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;     // Now we need to sort our objects into our new leafs  &lt;br /&gt;while( tree-&amp;gt;numberOfObjects &amp;gt; 0 )  &lt;br /&gt;{  &lt;br /&gt;ObjectCollideable *collideable = tree-&amp;gt;objects[0];  &lt;br /&gt;removeFromList( collideable, (void**)tree-&amp;gt;objects, &amp;amp;tree-&amp;gt;numberOfObjects );  &lt;br /&gt;removeFromList( tree, (void**)collideable-&amp;gt;octrees, &amp;amp;collideable-&amp;gt;numberOfOctrees );  &lt;br /&gt;&lt;br /&gt;UpdateCollisions( collideable );  &lt;br /&gt;&lt;br /&gt;for( uint i=0; i&amp;lt;8; ++i )  &lt;br /&gt;{  &lt;br /&gt;Octree *leaf = tree-&amp;gt;leafs[i];  &lt;br /&gt;if( OctreeIsInLeaf( leaf, &amp;amp;collideable-&amp;gt;min, &amp;amp;collideable-&amp;gt;max ) )  &lt;br /&gt;{  &lt;br /&gt;// Place this object in this leaf  &lt;br /&gt;leaf-&amp;gt;objects[leaf-&amp;gt;numberOfObjects++] = collideable;  &lt;br /&gt;assert( leaf-&amp;gt;numberOfObjects &amp;lt;= MAX_TREE_OBJECTS );  &lt;br /&gt;collideable-&amp;gt;octrees[collideable-&amp;gt;numberOfOctrees++] = leaf;  &lt;br /&gt;assert( collideable-&amp;gt;numberOfOctrees &amp;lt; MAX_OBJECT_TREES );  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now for removing an object from the tree, we simply check through all the leafs the object resides in and one by one remove the object from the trees list. We then set a call to prune the tree, so that if the leafs are no longer needed they'll be deleted.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; void OctreeRemoveObject(ObjectCollideable *collideable)  &lt;br /&gt;{  &lt;br /&gt;while( collideable-&amp;gt;numberOfOctrees &amp;gt; 0 )  &lt;br /&gt;{      &lt;br /&gt;Octree *tree = collideable-&amp;gt;octrees[0];  &lt;br /&gt;removeFromList( collideable, (void**)tree-&amp;gt;objects, &amp;amp;tree-&amp;gt;numberOfObjects );  &lt;br /&gt;removeFromList( tree, (void**)collideable-&amp;gt;octrees, &amp;amp;collideable-&amp;gt;numberOfOctrees );  &lt;br /&gt;&lt;br /&gt;if( tree-&amp;gt;numberOfObjects == 0 )  &lt;br /&gt;{  &lt;br /&gt;if( gEngine-&amp;gt;collideables-&amp;gt;pruneTrees &amp;lt;= 0.0f )  &lt;br /&gt;{  &lt;br /&gt;gEngine-&amp;gt;collideables-&amp;gt;pruneTrees = 1.0f;  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Above I set a timer to 1.0f which would count down elsewhere to call the prune tree function. With the prune tree function recursively calling itself on all it's leafs, and if the set of leafs have no objects in them they get deleted.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; void OctreePruneTree(Octree *tree)  &lt;br /&gt;{  &lt;br /&gt;if( tree-&amp;gt;leafs != nil )  &lt;br /&gt;{  &lt;br /&gt;BOOL hasObjects = OctreeHasObjects( tree );  &lt;br /&gt;if( hasObjects == NO )  &lt;br /&gt;{  &lt;br /&gt;OctreeDeleteLeafs( tree );  &lt;br /&gt;}  &lt;br /&gt;else  &lt;br /&gt;{  &lt;br /&gt;for( uint i=0; i&amp;lt;8; ++i )  &lt;br /&gt;{  &lt;br /&gt;OctreePruneTree( tree-&amp;gt;leafs[i] );  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;BOOL OctreeHasObjects(Octree *tree)  &lt;br /&gt;{  &lt;br /&gt;BOOL hasObjects = tree-&amp;gt;numberOfObjects &amp;gt; 0;  &lt;br /&gt;&lt;br /&gt;if( tree-&amp;gt;leafs != nil )  &lt;br /&gt;{  &lt;br /&gt;for( uint i=0; i&amp;lt;8 &amp;amp;&amp;amp; hasObjects == NO; ++i )  &lt;br /&gt;{  &lt;br /&gt;hasObjects |= OctreeHasObjects( tree-&amp;gt;leafs[i] );  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;return hasObjects;  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Again delete leafs works by recursively calling itself to free all the leafs inside.&lt;br /&gt;&lt;pre style="background-image: URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt; void OctreeDeleteLeafs(Octree *tree)  &lt;br /&gt;{  &lt;br /&gt;// Ensure all our leafs are deleted  &lt;br /&gt;if( tree-&amp;gt;leafs != nil )  &lt;br /&gt;{  &lt;br /&gt;for( uint i=0; i&amp;lt;8; ++i )  &lt;br /&gt;{  &lt;br /&gt;if( tree-&amp;gt;leafs[i] != nil )  &lt;br /&gt;{  &lt;br /&gt;Octree *leaf = tree-&amp;gt;leafs[i];  &lt;br /&gt;OctreeDeleteLeafs( leaf );  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;free( tree-&amp;gt;leafs );  &lt;br /&gt;tree-&amp;gt;leafs = nil;  &lt;br /&gt;}  &lt;br /&gt;}  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;That's it! Simply add in all your static objects, then whenever you move an object, just re-add it to the root tree, so it can put itself into the appropriate leafs.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-177947278002650794?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/177947278002650794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/01/octrees-code-and-walkthrough.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/177947278002650794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/177947278002650794'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/01/octrees-code-and-walkthrough.html' title='Octrees - Code and walkthrough'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-1987526964105645498</id><published>2010-01-08T06:40:00.000Z</published><updated>2011-03-26T03:00:02.465Z</updated><title type='text'>Widgets and function pointers</title><content type='html'>I'm currently working through the setting screens, so I needed to make a few widget classes. Basically I have a bunch of widgets which contain their position, size and some functions to determine how input is handled. Now comes the fun bit, re-using the class for different options. I wanted one widget to handle starting a new game, one for toggling collision boxes, etc.&lt;br /&gt;&lt;br /&gt;To get this done, I used function pointers. I'd let the scene handle the interactions with the widgets and when one was invoked, it's set callback was fired.&lt;br /&gt;&lt;br /&gt;So in the header file, I have two members, the first being the function to call, and second being the parameter to pass into the function.&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; @interface WidgetButton : WidgetBase   &lt;br /&gt; {  &lt;br /&gt;   @public  &lt;br /&gt;    void (*callback_routine)(void *data);  &lt;br /&gt;    void *callback_data;  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;When the widget is invoked, it then went ahead and fired it's function pointer.&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; -(BOOL)handleControls:(ScreenTouches*)screenTouch  &lt;br /&gt; {  &lt;br /&gt;   if( [super handleControls:screenTouch] )  &lt;br /&gt;   {  &lt;br /&gt;     if( callback_routine )  &lt;br /&gt;     {  &lt;br /&gt;       callback_routine( callback_data );  &lt;br /&gt;     }  &lt;br /&gt;     return YES;  &lt;br /&gt;   }  &lt;br /&gt;   return NO;  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;So in the case of toggling a bool on or off, in the main scene I'd create a widget and pass in the function pointer for toggling bools with the variable active.&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; activateWidget = [[WidgetButton alloc] init];  &lt;br /&gt; ((WidgetButton*)activateWidget)-&amp;gt;callback_routine = &amp;amp;toggleBool;  &lt;br /&gt; ((WidgetButton*)activateWidget)-&amp;gt;callback_data = &amp;amp;active;  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Finally, the function of toggleBool would simply toggle the bool.&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; void toggleBool(void *data)  &lt;br /&gt; {  &lt;br /&gt;   BOOL *toggle = (BOOL*)data;  &lt;br /&gt;   *toggle = !(*toggle);  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;So now we have a classes which encapsulate the drawing and user interaction, but provide differing responses.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-1987526964105645498?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/1987526964105645498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/01/widgets-and-function-pointers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1987526964105645498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1987526964105645498'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/01/widgets-and-function-pointers.html' title='Widgets and function pointers'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-2252706341072916665</id><published>2010-01-01T06:14:00.000Z</published><updated>2011-03-26T03:00:02.468Z</updated><title type='text'>iPhone - Unproject a 2D point</title><content type='html'>Alright, just added in support for selecting 3d objects using 2d coordinates. So you can select an object in a 3d scene using your finger. The idea to do this is to unproject the 2d coordinates passed in at 0 and 1 range to get the direction of the ray, then simply use that ray to find which objects collide.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Step one was to find the source for glu unProject function. There's loads of sources online for OpenGL, so all you need to do is port it over to OpenGL ES (just replace GLdouble with GLfloat).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's some source code ported from &lt;a href="http://code.google.com/p/iphone-glu"&gt;http://code.google.com/p/iphone-glu&lt;/a&gt;&lt;/div&gt;&lt;pre style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; static void __gluMultMatrixVecd(const GLfloat matrix[16], const GLfloat in[4], &lt;br /&gt;                                GLfloat out[4]) &lt;br /&gt;{ &lt;br /&gt;    int i; &lt;br /&gt;    for( i=0; i&amp;lt;4; ++i ) &lt;br /&gt;    { &lt;br /&gt;        out[i] =  &lt;br /&gt;        in[0] * matrix[0*4+i] + &lt;br /&gt;        in[1] * matrix[1*4+i] + &lt;br /&gt;        in[2] * matrix[2*4+i] + &lt;br /&gt;        in[3] * matrix[3*4+i]; &lt;br /&gt;    } &lt;br /&gt;} &lt;br /&gt;/* &lt;br /&gt; ** Invert 4x4 matrix. &lt;br /&gt; ** Contributed by David Moore (See Mesa bug #6748) &lt;br /&gt; */ &lt;br /&gt;static int __gluInvertMatrixd(const GLfloat m[16], GLfloat invOut[16]) &lt;br /&gt;{ &lt;br /&gt;    GLfloat inv[16]; &lt;br /&gt;    inv[0]    =  m[5]*m[10]*m[15]    - m[5]*m[11]*m[14]    - m[9]*m[6]*m[15] &lt;br /&gt;             + m[9]*m[7]*m[14]        + m[13]*m[6]*m[11]    - m[13]*m[7]*m[10]; &lt;br /&gt;    inv[4]    = - m[4]*m[10]*m[15]    + m[4]*m[11]*m[14]    + m[8]*m[6]*m[15] &lt;br /&gt;             - m[8]*m[7]*m[14]        - m[12]*m[6]*m[11]    + m[12]*m[7]*m[10]; &lt;br /&gt;    inv[8]    =  m[4]*m[9]*m[15]        - m[4]*m[11]*m[13]    - m[8]*m[5]*m[15] &lt;br /&gt;             + m[8]*m[7]*m[13]        + m[12]*m[5]*m[11]    - m[12]*m[7]*m[9]; &lt;br /&gt;    inv[12] = - m[4]*m[9]*m[14]        + m[4]*m[10]*m[13]    + m[8]*m[5]*m[14] &lt;br /&gt;             - m[8]*m[6]*m[13]        - m[12]*m[5]*m[10]    + m[12]*m[6]*m[9]; &lt;br /&gt;    inv[1]    = - m[1]*m[10]*m[15]    + m[1]*m[11]*m[14]    + m[9]*m[2]*m[15] &lt;br /&gt;             - m[9]*m[3]*m[14]        - m[13]*m[2]*m[11]    + m[13]*m[3]*m[10]; &lt;br /&gt;    inv[5]    =  m[0]*m[10]*m[15]    - m[0]*m[11]*m[14]    - m[8]*m[2]*m[15] &lt;br /&gt;             + m[8]*m[3]*m[14]        + m[12]*m[2]*m[11]    - m[12]*m[3]*m[10]; &lt;br /&gt;    inv[9]    = - m[0]*m[9]*m[15]        + m[0]*m[11]*m[13]    + m[8]*m[1]*m[15] &lt;br /&gt;             - m[8]*m[3]*m[13]        - m[12]*m[1]*m[11]    + m[12]*m[3]*m[9]; &lt;br /&gt;    inv[13] =  m[0]*m[9]*m[14]        - m[0]*m[10]*m[13]    - m[8]*m[1]*m[14] &lt;br /&gt;             + m[8]*m[2]*m[13]        + m[12]*m[1]*m[10]    - m[12]*m[2]*m[9]; &lt;br /&gt;    inv[2]    =  m[1]*m[6]*m[15]        - m[1]*m[7]*m[14]    - m[5]*m[2]*m[15] &lt;br /&gt;             + m[5]*m[3]*m[14]        + m[13]*m[2]*m[7]    - m[13]*m[3]*m[6]; &lt;br /&gt;    inv[6]    = - m[0]*m[6]*m[15]        + m[0]*m[7]*m[14]    + m[4]*m[2]*m[15] &lt;br /&gt;             - m[4]*m[3]*m[14]        - m[12]*m[2]*m[7]    + m[12]*m[3]*m[6]; &lt;br /&gt;    inv[10] =  m[0]*m[5]*m[15]        - m[0]*m[7]*m[13]    - m[4]*m[1]*m[15] &lt;br /&gt;             + m[4]*m[3]*m[13]        + m[12]*m[1]*m[7]    - m[12]*m[3]*m[5]; &lt;br /&gt;    inv[14] = - m[0]*m[5]*m[14]        + m[0]*m[6]*m[13]    + m[4]*m[1]*m[14] &lt;br /&gt;             - m[4]*m[2]*m[13]        - m[12]*m[1]*m[6]    + m[12]*m[2]*m[5]; &lt;br /&gt;    inv[3]    = - m[1]*m[6]*m[11]        + m[1]*m[7]*m[10]    + m[5]*m[2]*m[11] &lt;br /&gt;             - m[5]*m[3]*m[10]        - m[9]*m[2]*m[7]    + m[9]*m[3]*m[6]; &lt;br /&gt;    inv[7]    =  m[0]*m[6]*m[11]        - m[0]*m[7]*m[10]    - m[4]*m[2]*m[11] &lt;br /&gt;             + m[4]*m[3]*m[10]        + m[8]*m[2]*m[7]    - m[8]*m[3]*m[6]; &lt;br /&gt;    inv[11] = - m[0]*m[5]*m[11]        + m[0]*m[7]*m[9]    + m[4]*m[1]*m[11] &lt;br /&gt;             - m[4]*m[3]*m[9]        - m[8]*m[1]*m[7]    + m[8]*m[3]*m[5]; &lt;br /&gt;    inv[15] =  m[0]*m[5]*m[10]        - m[0]*m[6]*m[9]    - m[4]*m[1]*m[10] &lt;br /&gt;             + m[4]*m[2]*m[9]        + m[8]*m[1]*m[6]    - m[8]*m[2]*m[5]; &lt;br /&gt;    GLfloat det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12]; &lt;br /&gt;    if( det == 0 ) &lt;br /&gt;    { &lt;br /&gt;        return GL_FALSE; &lt;br /&gt;    } &lt;br /&gt;    det = 1.0 / det; &lt;br /&gt;    for( int i=0; i&amp;lt;16; ++i ) &lt;br /&gt;    { &lt;br /&gt;        invOut[i] = inv[i] * det; &lt;br /&gt;    } &lt;br /&gt;    return GL_TRUE; &lt;br /&gt;} &lt;br /&gt;static void __gluMultMatricesd(const GLfloat a[16], const GLfloat b[16], &lt;br /&gt;                              GLfloat r[16]) &lt;br /&gt;{ &lt;br /&gt;    int i, j; &lt;br /&gt;    for( i=0; i&amp;lt;4; ++i )  &lt;br /&gt;    { &lt;br /&gt;        for( j=0; j&amp;lt;4; ++j )  &lt;br /&gt;        { &lt;br /&gt;            r[i*4+j] =  &lt;br /&gt;            a[i*4+0]*b[0*4+j] + &lt;br /&gt;            a[i*4+1]*b[1*4+j] + &lt;br /&gt;            a[i*4+2]*b[2*4+j] + &lt;br /&gt;            a[i*4+3]*b[3*4+j]; &lt;br /&gt;        } &lt;br /&gt;    } &lt;br /&gt;} &lt;br /&gt;BOOL gluUnProject(GLfloat winx, GLfloat winy, GLfloat winz, &lt;br /&gt;                 const GLfloat modelMatrix[16],  &lt;br /&gt;                 const GLfloat projMatrix[16], &lt;br /&gt;                 const GLint viewport[4], &lt;br /&gt;                 GLfloat *objx, GLfloat *objy, GLfloat *objz) &lt;br /&gt;{ &lt;br /&gt;    GLfloat finalMatrix[16]; &lt;br /&gt;    GLfloat in[4]; &lt;br /&gt;    GLfloat out[4]; &lt;br /&gt;    __gluMultMatricesd( modelMatrix, projMatrix, finalMatrix ); &lt;br /&gt;    if( !__gluInvertMatrixd( finalMatrix, finalMatrix ) )  &lt;br /&gt;    { &lt;br /&gt;        return NO; &lt;br /&gt;    } &lt;br /&gt;    in[0] = winx; &lt;br /&gt;    in[1] = winy; &lt;br /&gt;    in[2] = winz; &lt;br /&gt;    in[3] = 1.0; &lt;br /&gt;    /* Map x and y from window coordinates */ &lt;br /&gt;    in[0] = ( in[0] - viewport[0] ) / viewport[2]; &lt;br /&gt;    in[1] = ( in[1] - viewport[1] ) / viewport[3]; &lt;br /&gt;    /* Map to range -1 to 1 */ &lt;br /&gt;    in[0] = in[0] * 2 - 1; &lt;br /&gt;    in[1] = in[1] * 2 - 1; &lt;br /&gt;    in[2] = in[2] * 2 - 1; &lt;br /&gt;    __gluMultMatrixVecd(finalMatrix, in, out); &lt;br /&gt;    if( out[3] == 0.0 ) &lt;br /&gt;    { &lt;br /&gt;        return NO; &lt;br /&gt;    } &lt;br /&gt;    out[0] /= out[3]; &lt;br /&gt;    out[1] /= out[3]; &lt;br /&gt;    out[2] /= out[3]; &lt;br /&gt;    *objx = out[0]; &lt;br /&gt;    *objy = out[1]; &lt;br /&gt;    *objz = out[2]; &lt;br /&gt;    return YES; &lt;br /&gt;} &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;Step two take in a 2d coordinate and feed it into the collision detection system. My collision system scans through all base objects of ObjectCollideable and returns the one which is closest to the start of the ray. The viewport and projection matrices are calculated on OpenGL initialisation with the following calls.&lt;/div&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; ObjectCollideable* Projection2DScan(CGPoint point)  &lt;br /&gt; {  &lt;br /&gt;    GLfloat modelViewMatrix[16];  &lt;br /&gt;    glGetFloatv( GL_MODELVIEW_MATRIX, modelViewMatrix );  &lt;br /&gt;   &lt;br /&gt;    point.y = 1.0f - point.x;  &lt;br /&gt;    point.x *= gView-&amp;gt;viewport[2];  &lt;br /&gt;    point.y *= gView-&amp;gt;viewport[3];  &lt;br /&gt;   &lt;br /&gt;    Vector3 nearPlane, farPlane;  &lt;br /&gt;    gluUnProject( point.x, point.y, 0.0f, modelViewMatrix, gView-&amp;gt;projectionMatrix, gView-&amp;gt;viewport, &amp;amp;nearPlane.x, &amp;amp;nearPlane.y, &amp;amp;nearPlane.z );  &lt;br /&gt;    gluUnProject( point.x, point.y, 1.0f, modelViewMatrix, gView-&amp;gt;projectionMatrix, gView-&amp;gt;viewport, &amp;amp;farPlane.x, &amp;amp;farPlane.y, &amp;amp;farPlane.z );  &lt;br /&gt;   &lt;br /&gt;    // Figure out our ray's direction  &lt;br /&gt;    Vector3 direction = farPlane;  &lt;br /&gt;    Vector3Sub( &amp;amp;direction, &amp;amp;nearPlane );  &lt;br /&gt;    Vector3Normalize( &amp;amp;direction );  &lt;br /&gt;   &lt;br /&gt;    // Cast the ray from our near plane  &lt;br /&gt;    Vector3 farPoint = Vector3MulResult( &amp;amp;direction, 500.0f );  &lt;br /&gt;    Vector3Add( &amp;amp;farPoint, &amp;amp;nearPlane );  &lt;br /&gt;   &lt;br /&gt;    Vector3 hitLocation;  &lt;br /&gt;    ObjectCollideable *hitObject = BasicLineCollisionCheck( &amp;amp;nearPlane, &amp;amp;farPoint, &amp;amp;hitLocation, gEngine-&amp;gt;collideables );  &lt;br /&gt;    return hitObject;  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;That's it, your collision system can now use that ray to return the closest hit object.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-2252706341072916665?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/2252706341072916665/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2010/01/iphone-unproject-2d-point.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/2252706341072916665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/2252706341072916665'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2010/01/iphone-unproject-2d-point.html' title='iPhone - Unproject a 2D point'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-7864439152464244950</id><published>2009-12-31T08:59:00.000Z</published><updated>2011-03-26T03:00:02.473Z</updated><title type='text'>iPhone - Serialize this</title><content type='html'>Just implemented saving and loading. It's really really really simple to do.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The basic concept is the following.&lt;/div&gt;&lt;div&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;// Grab the default archive&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;NSUserDefaults&lt;span style="color: #000000"&gt; *archive = [&lt;/span&gt;NSUserDefaults&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;standardUserDefaults&lt;/span&gt;&lt;span style="color: #000000"&gt;];&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;// Create a magic key for the value you're about to load or save&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;NSString *key = &lt;span class="Apple-style-span" style="color: rgb(46, 13, 110); "&gt;&lt;span style="color: #000000"&gt;[[&lt;/span&gt;&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;alloc&lt;span style="color: #000000"&gt;] &lt;/span&gt;initWithFormat&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #c41a16"&gt;@"myData"];&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;// To save&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;span class="Apple-style-span"  style="color:#000000;"&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;[archive &lt;span style="color: #2e0d6e"&gt;setFloat&lt;/span&gt;:vector-&gt;&lt;span style="color: #5c2699"&gt;x&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;forKey&lt;/span&gt;:vectorKeyX];&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;// To load&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;vector-&gt;&lt;span style="color: #5c2699"&gt;x&lt;/span&gt; = [archive &lt;span style="color: #2e0d6e"&gt;floatForKey&lt;/span&gt;:vectorKeyX];&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;// Don't forget to release the key&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;[key release];&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;Armed with these tools I went with the approach to save out as much of the game state required to re-launch the game back into same state. To do this I set up the engine to process a number of scenes. Each scene is responsible for a number of objects. When I save out the game data, I go through all the objects and save out what scene they're in, so on launch, I reload all the scenes that were currently loaded, which will then create all the required objects. I then pass through all the objects and load in the required data to get them working the way they were.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I organised my objects to create unique keys depending on their object index and the internal data index I was processing. Enough talk, here's the code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;// Creates the unique key for our object&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;+(&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt;*)getSerializeKey:(&lt;span style="color: #5c2699"&gt;uint&lt;/span&gt;)index key:(&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt;*)key&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #aa0d91"&gt;if&lt;/span&gt;( key == &lt;span style="color: #aa0d91"&gt;nil&lt;/span&gt; )&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #2e0d6e"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style="color: #aa0d91"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt; [[&lt;/span&gt;&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt;&lt;span style="color: #000000"&gt; &lt;/span&gt;alloc&lt;span style="color: #000000"&gt;] &lt;/span&gt;initWithFormat&lt;span style="color: #000000"&gt;:&lt;/span&gt;&lt;span style="color: #c41a16"&gt;@"Obj%i"&lt;/span&gt;&lt;span style="color: #000000"&gt;, index];&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #aa0d91"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;else&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;span style="color: #aa0d91"&gt;return&lt;/span&gt; [[&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;alloc&lt;/span&gt;] &lt;span style="color: #2e0d6e"&gt;initWithFormat&lt;/span&gt;:&lt;span style="color: #c41a16"&gt;@"%@Obj%i"&lt;/span&gt;, key, index];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;// Creates our key and passes it into the serializeInternals function for saving the internal data&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;-(&lt;span style="color: #aa0d91"&gt;void&lt;/span&gt;)serialize:(&lt;span style="color: #5c2699"&gt;NSUserDefaults&lt;/span&gt;*)archive saving:(&lt;span style="color: #aa0d91"&gt;BOOL&lt;/span&gt;)saving key:(&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt;*)key index:(&lt;span style="color: #5c2699"&gt;uint&lt;/span&gt;)index&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; *objectKey = [&lt;span style="color: #3f6e74"&gt;ObjectBase&lt;/span&gt; &lt;span style="color: #26474b"&gt;getSerializeKey&lt;/span&gt;:index &lt;span style="color: #26474b"&gt;key&lt;/span&gt;:(&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt;*)&lt;span style="color: #2e0d6e"&gt;key&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;// The internal index will aid the creation of unique keys for our internal data&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #5c2699"&gt;uint&lt;/span&gt; internalIndex = &lt;span style="color: #1c00cf"&gt;0&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[&lt;span style="color: #aa0d91"&gt;self&lt;/span&gt; serializeInternals:archive saving:saving key:key index:&amp;amp;internalIndex];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[objectKey &lt;span style="color: #2e0d6e"&gt;release&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;// Overridden by child classes to save more data&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;-(&lt;span style="color: #aa0d91"&gt;void&lt;/span&gt;)serializeInternals:(&lt;span style="color: #5c2699"&gt;NSUserDefaults&lt;/span&gt;*)archive saving:(&lt;span style="color: #aa0d91"&gt;BOOL&lt;/span&gt;)saving key:(&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt;*)key index:(&lt;span style="color: #5c2699"&gt;uint&lt;/span&gt;*)index&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;{&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;// Save our object position by default&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[&lt;span style="color: #aa0d91"&gt;self&lt;/span&gt; &lt;span style="color: #26474b"&gt;serializeVector&lt;/span&gt;:&amp;amp;position &lt;span style="color: #26474b"&gt;archive&lt;/span&gt;:archive &lt;span style="color: #26474b"&gt;saving&lt;/span&gt;:saving &lt;span style="color: #26474b"&gt;key&lt;/span&gt;:key &lt;span style="color: #26474b"&gt;index&lt;/span&gt;:index];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;// Save/load our scenes with a unique scene key&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;+(&lt;span style="color: #aa0d91"&gt;void&lt;/span&gt;)serializeScene:(&lt;span style="color: #3f6e74"&gt;SceneBase&lt;/span&gt;*)scene archive:(&lt;span style="color: #5c2699"&gt;NSUserDefaults&lt;/span&gt;*)archive saving:(&lt;span style="color: #aa0d91"&gt;BOOL&lt;/span&gt;)saving key:(&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt;*)key&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; *sceneKey = [[&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;alloc&lt;/span&gt;] &lt;span style="color: #2e0d6e"&gt;initWithFormat&lt;/span&gt;:&lt;span style="color: #c41a16"&gt;@"%@Scene"&lt;/span&gt;, &lt;span style="color: #2e0d6e"&gt;key&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #aa0d91"&gt;if&lt;/span&gt;( saving )&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;[archive &lt;span style="color: #2e0d6e"&gt;setInteger&lt;/span&gt;:scene ? scene-&gt;&lt;span style="color: #3f6e74"&gt;index&lt;/span&gt; : -&lt;span style="color: #1c00cf"&gt;1&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;forKey&lt;/span&gt;:sceneKey];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #aa0d91"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;else&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;span style="color: #5c2699"&gt;NSInteger&lt;/span&gt; sceneIndex = [archive &lt;span style="color: #2e0d6e"&gt;integerForKey&lt;/span&gt;:sceneKey];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;[&lt;span style="color: #3f6e74"&gt;gEngine&lt;/span&gt; &lt;span style="color: #26474b"&gt;addScene&lt;/span&gt;:sceneIndex];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[sceneKey &lt;span style="color: #2e0d6e"&gt;release&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;// The keys for the objects internal vectors are concatenated by the object key and the internal index key&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;-(&lt;span style="color: #aa0d91"&gt;void&lt;/span&gt;)serializeVector:(&lt;span style="color: #3f6e74"&gt;Vector3&lt;/span&gt;*)vector archive:(&lt;span style="color: #5c2699"&gt;NSUserDefaults&lt;/span&gt;*)archive saving:(&lt;span style="color: #aa0d91"&gt;BOOL&lt;/span&gt;)saving key:(&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt;*)key index:(&lt;span style="color: #5c2699"&gt;uint&lt;/span&gt;*)index&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; *vectorKeyX = [[&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;alloc&lt;/span&gt;] &lt;span style="color: #2e0d6e"&gt;initWithFormat&lt;/span&gt;:&lt;span style="color: #c41a16"&gt;@"%@Vector%iX"&lt;/span&gt;, key, *index];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; *vectorKeyY = [[&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;alloc&lt;/span&gt;] &lt;span style="color: #2e0d6e"&gt;initWithFormat&lt;/span&gt;:&lt;span style="color: #c41a16"&gt;@"%@Vector%iY"&lt;/span&gt;, key, *index];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; *vectorKeyZ = [[&lt;span style="color: #5c2699"&gt;NSString&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;alloc&lt;/span&gt;] &lt;span style="color: #2e0d6e"&gt;initWithFormat&lt;/span&gt;:&lt;span style="color: #c41a16"&gt;@"%@Vector%iZ"&lt;/span&gt;, key, *index];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #aa0d91"&gt;if&lt;/span&gt;( saving )&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;[archive &lt;span style="color: #2e0d6e"&gt;setFloat&lt;/span&gt;:vector-&gt;&lt;span style="color: #5c2699"&gt;x&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;forKey&lt;/span&gt;:vectorKeyX];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;[archive &lt;span style="color: #2e0d6e"&gt;setFloat&lt;/span&gt;:vector-&gt;&lt;span style="color: #5c2699"&gt;y&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;forKey&lt;/span&gt;:vectorKeyY];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;[archive &lt;span style="color: #2e0d6e"&gt;setFloat&lt;/span&gt;:vector-&gt;&lt;span style="color: #5c2699"&gt;z&lt;/span&gt; &lt;span style="color: #2e0d6e"&gt;forKey&lt;/span&gt;:vectorKeyZ];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #aa0d91"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;else&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;vector-&gt;&lt;span style="color: #5c2699"&gt;x&lt;/span&gt; = [archive &lt;span style="color: #2e0d6e"&gt;floatForKey&lt;/span&gt;:vectorKeyX];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;vector-&gt;&lt;span style="color: #5c2699"&gt;y&lt;/span&gt; = [archive &lt;span style="color: #2e0d6e"&gt;floatForKey&lt;/span&gt;:vectorKeyY];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;vector-&gt;&lt;span style="color: #5c2699"&gt;z&lt;/span&gt; = [archive &lt;span style="color: #2e0d6e"&gt;floatForKey&lt;/span&gt;:vectorKeyZ];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[vectorKeyX &lt;span style="color: #2e0d6e"&gt;release&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[vectorKeyY &lt;span style="color: #2e0d6e"&gt;release&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[vectorKeyZ &lt;span style="color: #2e0d6e"&gt;release&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;(*index)++;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;}&lt;/p&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="font-family:Monaco, serif;font-size:85%;"&gt;&lt;span class="Apple-style-span" style="font-size: 10px; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;That's the basic jist of it, create unique keys for saving and loading the data.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-7864439152464244950?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/7864439152464244950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/12/iphone-serialize-this.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7864439152464244950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7864439152464244950'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/12/iphone-serialize-this.html' title='iPhone - Serialize this'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-1221383569967157993</id><published>2009-12-28T01:27:00.000Z</published><updated>2011-03-26T03:00:02.478Z</updated><title type='text'>iPhone - Posix Threads for the win</title><content type='html'>So I've been looking into multithreading my iphone engine. Switching from using a timer to threads bumped up my frame rate by about 10% instantly. I found that using Posix threads were slightly (1-2%) faster than NSThreads. Currently, I've set my engine up to have 2 additional threads. One to handle the game updating and rendering, and a second to handling job loading, with jobs being streaming in audio and textures. To handle synchronisation I'm using spin locks, which are basically while loops.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Things to note&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;When setting up your thread you must always, start and release an NSAutoRelease pool.&lt;/li&gt;&lt;li&gt;The pool should be restarted every now and then to release the objects released during the runtime of the thread.&lt;/li&gt;&lt;li&gt;When using Posix threads it's recommended you run an empty NSThread just to let the OS know that the app will be multithreaded.&lt;/li&gt;&lt;li&gt;Setting up an OpenAL context stalls the engine by around half a second on start up, so I tend to launch it in the jobs thread to avoid stalls.&lt;/li&gt;&lt;li&gt;Bumping up the priority of the render thread does improve performance slightly.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Sample code&lt;/b&gt;&lt;/div&gt;&lt;div&gt;When called the start function will launch a dummy thread which does nothing, so the thread will terminate immediately. It then launches two threads, a game thread and a jobs thread. The game thread is given a higher priority than the jobs thread.&lt;/div&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;-(&lt;span style="color: rgb(170, 13, 145); "&gt;void&lt;/span&gt;)start&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;{&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(0, 116, 0); "&gt;&lt;span style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/span&gt;// iPhone SDK recommends launching an empty NSThread when using POSIX threads with Cocoa applications&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(46, 13, 110); "&gt;&lt;span style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;[&lt;/span&gt;&lt;span style="color: rgb(92, 38, 153); "&gt;NSThread&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); "&gt; &lt;/span&gt;detachNewThreadSelector&lt;span style="color: rgb(0, 0, 0); "&gt;:&lt;/span&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;@selector&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); "&gt;( emptyThread ) &lt;/span&gt;toTarget&lt;span style="color: rgb(0, 0, 0); "&gt;:&lt;/span&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;self&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); "&gt; &lt;/span&gt;withObject&lt;span style="color: rgb(0, 0, 0); "&gt;:&lt;/span&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;nil&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); "&gt;]; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; min-height: 14px; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(0, 116, 0); "&gt;&lt;span style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/span&gt;// Create the game thread using POSIX routines.&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(38, 71, 75); "&gt;createThread&lt;/span&gt;( &amp;amp;PosixGameThread, &lt;span style="color: rgb(170, 13, 145); "&gt;self&lt;/span&gt;, &lt;span style="color: rgb(28, 0, 207); "&gt;0&lt;/span&gt;, +&lt;span style="color: rgb(28, 0, 207); "&gt;2&lt;/span&gt; );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; min-height: 14px; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(0, 116, 0); "&gt;&lt;span style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/span&gt;// Create the jobs thread&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(38, 71, 75); "&gt;createThread&lt;/span&gt;( &amp;amp;PosixJobsThread, &lt;span style="color: rgb(170, 13, 145); "&gt;self&lt;/span&gt;, &lt;span style="color: rgb(28, 0, 207); "&gt;0&lt;/span&gt;, -&lt;span style="color: rgb(28, 0, 207); "&gt;2&lt;/span&gt; );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;}&lt;/p&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;Empty thread does nothing, so the thread will terminate naturally upon launching.&lt;/div&gt;&lt;div&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;-(&lt;span style="color: rgb(170, 13, 145); "&gt;void&lt;/span&gt;)emptyThread&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;{&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;}&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-style-span"   style="font-family:Georgia, serif;font-size:130%;"&gt;&lt;span class="Apple-style-span" style="font-size: 16px;"&gt;Create Thread wraps the PSIOX routines required to launch a thread with a set priority.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; font-size: 16px; "&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;void&lt;/span&gt; createThread(&lt;span style="color: rgb(170, 13, 145); "&gt;void&lt;/span&gt; *(*start_routine)(&lt;span style="color: rgb(170, 13, 145); "&gt;void&lt;/span&gt;*), &lt;span style="color: rgb(170, 13, 145); "&gt;void&lt;/span&gt; *&lt;span style="color: rgb(170, 13, 145); "&gt;restrict&lt;/span&gt; arg, &lt;span style="color: rgb(170, 13, 145); "&gt;int&lt;/span&gt; prioritySet, &lt;span style="color: rgb(170, 13, 145); "&gt;int&lt;/span&gt; priorityAdj)&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;{&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(0, 116, 0); "&gt;&lt;span style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/span&gt;// Create the game thread using POSIX routines.&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(92, 38, 153); "&gt;&lt;span style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/span&gt;pthread_attr_t&lt;span style="color: rgb(0, 0, 0); "&gt; attr;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(92, 38, 153); "&gt;pthread_t&lt;/span&gt; posixThreadID;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;int&lt;/span&gt; returnVal;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; min-height: 14px; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;returnVal = &lt;span style="color: rgb(46, 13, 110); "&gt;pthread_attr_init&lt;/span&gt;( &amp;amp;attr );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(100, 56, 32); "&gt;assert&lt;/span&gt;( !returnVal );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; min-height: 14px; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(46, 13, 110); "&gt;&lt;span style="color: rgb(0, 0, 0); "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;returnVal = &lt;/span&gt;pthread_attr_setdetachstate&lt;span style="color: rgb(0, 0, 0); "&gt;( &amp;amp;attr, &lt;/span&gt;&lt;span style="color: rgb(100, 56, 32); "&gt;PTHREAD_CREATE_DETACHED&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); "&gt; );&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(100, 56, 32); "&gt;assert&lt;/span&gt;( !returnVal );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; min-height: 14px; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;returnVal = &lt;span style="color: rgb(46, 13, 110); "&gt;pthread_create&lt;/span&gt;( &amp;amp;posixThreadID, &amp;amp;attr, start_routine, arg );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(100, 56, 32); "&gt;assert&lt;/span&gt;( !returnVal );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; min-height: 14px; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;struct&lt;/span&gt; sched_param param;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;int&lt;/span&gt; policy;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(46, 13, 110); "&gt;pthread_getschedparam&lt;/span&gt;( posixThreadID, &amp;amp;policy, &amp;amp;param );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(100, 56, 32); "&gt;assert&lt;/span&gt;( !returnVal );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; min-height: 14px; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;if&lt;/span&gt;( prioritySet != &lt;span style="color: rgb(28, 0, 207); "&gt;0&lt;/span&gt; )&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;{&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;param.&lt;span style="color: rgb(92, 38, 153); "&gt;sched_priority&lt;/span&gt; = prioritySet;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;}&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;else&lt;/span&gt; &lt;span style="color: rgb(170, 13, 145); "&gt;if&lt;/span&gt;( priorityAdj != &lt;span style="color: rgb(28, 0, 207); "&gt;0&lt;/span&gt; )&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;{&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;param.&lt;span style="color: rgb(92, 38, 153); "&gt;sched_priority&lt;/span&gt; += priorityAdj;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;}&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(100, 56, 32); "&gt;assert&lt;/span&gt;( param.&lt;span style="color: rgb(92, 38, 153); "&gt;sched_priority&lt;/span&gt; &gt; &lt;span style="color: rgb(28, 0, 207); "&gt;0&lt;/span&gt; &amp;amp;&amp;amp; param.&lt;span style="color: rgb(92, 38, 153); "&gt;sched_priority&lt;/span&gt; &lt; &lt;span style="color: rgb(28, 0, 207); "&gt;100&lt;/span&gt; );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; min-height: 14px; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;returnVal = &lt;span style="color: rgb(46, 13, 110); "&gt;pthread_setschedparam&lt;/span&gt;( posixThreadID, policy, &amp;amp;param );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(100, 56, 32); "&gt;assert&lt;/span&gt;( !returnVal );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; min-height: 14px; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;returnVal = &lt;span style="color: rgb(46, 13, 110); "&gt;pthread_attr_destroy&lt;/span&gt;( &amp;amp;attr );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(100, 56, 32); "&gt;assert&lt;/span&gt;( !returnVal );&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;}&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="font-family:Monaco, serif;font-size:85%;"&gt;&lt;span class="Apple-style-span" style="font-size: 10px;"&gt;&lt;span class="Apple-style-span"   style="font-family:Georgia, serif;font-size:130%;"&gt;&lt;span class="Apple-style-span" style="font-size: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The game thread owns the OpenGL context and spins around the while loop updating the frames while the game is running, while making a call lazily to refreshReleasePool to restart the pool.&lt;/div&gt;&lt;div&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span style="color: #aa0d91"&gt;void&lt;/span&gt;* PosixGameThread(&lt;span style="color: #aa0d91"&gt;void&lt;/span&gt;* data)&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #007400"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;// Note: autorelease pools should be created and released more frequentley if using this feature&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;NSAutoreleasePool&lt;span style="color: #000000"&gt; *pool = [[&lt;/span&gt;NSAutoreleasePool&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;alloc&lt;/span&gt;&lt;span style="color: #000000"&gt;] &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;init&lt;/span&gt;&lt;span style="color: #000000"&gt;];&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #5c2699"&gt;uint&lt;/span&gt; poolRefreshCounter = &lt;span style="color: #1c00cf"&gt;0&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #3f6e74"&gt;EAGLView&lt;/span&gt; *view = (&lt;span style="color: #3f6e74"&gt;EAGLView&lt;/span&gt;*)data;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #26474b"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[view &lt;/span&gt;setupGameThread&lt;span style="color: #000000"&gt;];&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[pool &lt;span style="color: #2e0d6e"&gt;release&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;pool = [[&lt;/span&gt;NSAutoreleasePool&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;alloc&lt;/span&gt;&lt;span style="color: #000000"&gt;] &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;init&lt;/span&gt;&lt;span style="color: #000000"&gt;];&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;view-&gt;&lt;span style="color: #3f6e74"&gt;runningGame&lt;/span&gt; = &lt;span style="color: #aa0d91"&gt;YES&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #aa0d91"&gt;while&lt;/span&gt;( view-&gt;&lt;span style="color: #3f6e74"&gt;runningGame&lt;/span&gt; )&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;span style="color: #aa0d91"&gt;if&lt;/span&gt;( view-&gt;&lt;span style="color: #3f6e74"&gt;paused&lt;/span&gt; == &lt;span style="color: #aa0d91"&gt;NO&lt;/span&gt; )&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;[view &lt;span style="color: #2e0d6e"&gt;update&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #643820"&gt;#if DEBUGON &amp;amp;&amp;amp; TARGET_IPHONE_SIMULATOR&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #007400"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;&lt;/span&gt;// 20 frames a second in debug&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;usleep&lt;/span&gt;( &lt;span style="color: #1c00cf"&gt;50000&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #643820"&gt;#endif&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;span style="color: #26474b"&gt;refreshReleasePool&lt;/span&gt;( &amp;amp;pool, &amp;amp;poolRefreshCounter, &lt;span style="color: #1c00cf"&gt;100&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[view &lt;span style="color: #26474b"&gt;shutdown&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[pool &lt;span style="color: #2e0d6e"&gt;release&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #aa0d91"&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;return&lt;span style="color: #000000"&gt; &lt;/span&gt;NULL&lt;span style="color: #000000"&gt;;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; font-size: 16px; "&gt;The jobs thread works the same way as the game thread, but owns the OpenAL context instead and starts the file I/O operations requested by the game thread.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span style="color: #aa0d91"&gt;void&lt;/span&gt;* PosixJobsThread(&lt;span style="color: #aa0d91"&gt;void&lt;/span&gt;* data)&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #5c2699"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;NSAutoreleasePool&lt;span style="color: #000000"&gt; *pool = [[&lt;/span&gt;NSAutoreleasePool&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;alloc&lt;/span&gt;&lt;span style="color: #000000"&gt;] &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;init&lt;/span&gt;&lt;span style="color: #000000"&gt;];&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #5c2699"&gt;uint&lt;/span&gt; poolRefreshCounter = &lt;span style="color: #1c00cf"&gt;0&lt;/span&gt;;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #3f6e74"&gt;EAGLView&lt;/span&gt; *view = (&lt;span style="color: #3f6e74"&gt;EAGLView&lt;/span&gt;*)data;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #aa0d91"&gt;while&lt;/span&gt;( view-&gt;&lt;span style="color: #3f6e74"&gt;runningGame&lt;/span&gt; == &lt;span style="color: #aa0d91"&gt;NO&lt;/span&gt; )&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;usleep&lt;/span&gt;( &lt;span style="color: #1c00cf"&gt;1000000&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #3f6e74"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[view-&gt;&lt;/span&gt;audioManager&lt;span style="color: #000000"&gt; &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;load&lt;/span&gt;&lt;span style="color: #000000"&gt;];&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;usleep&lt;/span&gt;( &lt;span style="color: #1c00cf"&gt;200000&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span style="color: #aa0d91"&gt;while&lt;/span&gt;( view-&gt;&lt;span style="color: #3f6e74"&gt;runningGame&lt;/span&gt; )&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;span style="color: #aa0d91"&gt;if&lt;/span&gt;( [view &lt;span style="color: #26474b"&gt;startJobs&lt;/span&gt;] )&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #007400"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;&lt;/span&gt;// 5 jobs a second&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;usleep&lt;/span&gt;( &lt;span style="color: #1c00cf"&gt;200000&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #aa0d91"&gt;&lt;span style="color: #000000"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;/span&gt;else&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;{&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;&lt;span style="color: #2e0d6e"&gt;usleep&lt;/span&gt;( &lt;span style="color: #1c00cf"&gt;1000000&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;span style="color: #26474b"&gt;refreshReleasePool&lt;/span&gt;( &amp;amp;pool, &amp;amp;poolRefreshCounter, &lt;span style="color: #1c00cf"&gt;10&lt;/span&gt; );&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;[pool &lt;span style="color: #2e0d6e"&gt;release&lt;/span&gt;];&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; color: #aa0d91"&gt;&lt;span style="color: #000000"&gt;    &lt;/span&gt;return&lt;span style="color: #000000"&gt; &lt;/span&gt;NULL&lt;span style="color: #000000"&gt;;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco"&gt;}&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; font-size: 16px; "&gt;Refresh Release Pool handles, reseting the NSAutoreleasePool lazily for both threads.&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Monaco; min-height: 14.0px"&gt;&lt;span class="Apple-style-span" style="font-family: Georgia, serif; font-size: 16px; "&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;void&lt;/span&gt; refreshReleasePool(&lt;span style="color: rgb(92, 38, 153); "&gt;NSAutoreleasePool&lt;/span&gt; **pool, &lt;span style="color: rgb(92, 38, 153); "&gt;uint&lt;/span&gt; *count, &lt;span style="color: rgb(170, 13, 145); "&gt;const&lt;/span&gt; &lt;span style="color: rgb(92, 38, 153); "&gt;uint&lt;/span&gt; target)&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;{&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span style="color: rgb(170, 13, 145); "&gt;if&lt;/span&gt;( (*count)++ &gt; target )&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;{&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;[*pool &lt;span style="color: rgb(46, 13, 110); "&gt;release&lt;/span&gt;];&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;*pool = [[&lt;span style="color: rgb(92, 38, 153); "&gt;NSAutoreleasePool&lt;/span&gt; &lt;span style="color: rgb(46, 13, 110); "&gt;alloc&lt;/span&gt;] &lt;span style="color: rgb(46, 13, 110); "&gt;init&lt;/span&gt;];&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;*count = &lt;span style="color: rgb(28, 0, 207); "&gt;0&lt;/span&gt;;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;}&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;}&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; "&gt;&lt;span class="Apple-style-span"   style="font-family:Georgia, serif;font-size:130%;"&gt;&lt;span class="Apple-style-span" style="font-size: 16px;"&gt;Any questions? Feel free to ask.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-1221383569967157993?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/1221383569967157993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/12/iphone-posix-threads-for-win.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1221383569967157993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1221383569967157993'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/12/iphone-posix-threads-for-win.html' title='iPhone - Posix Threads for the win'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-4915380959357995682</id><published>2009-12-23T00:35:00.002Z</published><updated>2009-12-23T00:39:10.908Z</updated><title type='text'>Stock market listings bug</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre-wrap; "&gt;Just patched a lingering stock market listing bug. The API we get the latest stock market lists and news feeds from have been modified.&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"   style="font-family:monospace;font-size:100%;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px; white-space: pre-wrap;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre-wrap; "&gt;I've patched the market lists today, so you should now have the correct stock market listing (in case any new companies have been added/removed from the markets) and I'll get the news feed fixed soon.&lt;/span&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre-wrap; "&gt; &lt;div&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-4915380959357995682?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/4915380959357995682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/12/stock-market-listings-bug.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4915380959357995682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4915380959357995682'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/12/stock-market-listings-bug.html' title='Stock market listings bug'/><author><name>SoftPoetry</name><uri>http://www.blogger.com/profile/12124821014237124632</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-YdNpmcI2SPU/TY1sjrV1peI/AAAAAAAAAAo/QZ4cbNSsIOQ/s220/softpoetry.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-6872009071193873820</id><published>2009-11-15T21:14:00.003Z</published><updated>2009-11-15T21:19:34.146Z</updated><title type='text'>Stock news date search</title><content type='html'>Finally got some spare time to devote back on this project. Noticed that the stock news date search wasn't working any more, so quickly patched it up.&lt;br /&gt;&lt;br /&gt;&lt;iframe name="iGrapher" src="http://igrapher.com/index_iframe.php?#iframe?1;intro?0;resizer?0;stock?RBS.L:FTSE;newsfordate?RBS.L,FTSE,12-Nov-09;news?RBS.L:FTSE:NEWS;" frameborder="1" width="600" height="350" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-6872009071193873820?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/6872009071193873820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/11/stock-news-date-search.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6872009071193873820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6872009071193873820'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/11/stock-news-date-search.html' title='Stock news date search'/><author><name>SoftPoetry</name><uri>http://www.blogger.com/profile/12124821014237124632</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-YdNpmcI2SPU/TY1sjrV1peI/AAAAAAAAAAo/QZ4cbNSsIOQ/s220/softpoetry.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-4555062878870323328</id><published>2009-09-09T16:14:00.000+01:00</published><updated>2011-03-26T03:00:02.486Z</updated><title type='text'>iPhone - It's been one week</title><content type='html'>So I spent the last week working on modelling, lighting, cartoon rendering and animations...&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_6gAcZl1znWE/SqfGhS-kzBI/AAAAAAAAAAM/sXhWlQ0Fn78/s1600-h/10527_127356286546_506556546_2538898_1506419_n.jpg"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; WIDTH: 240px; HEIGHT: 320px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5379486555249626130" border="0" alt="" src="http://3.bp.blogspot.com/_6gAcZl1znWE/SqfGhS-kzBI/AAAAAAAAAAM/sXhWlQ0Fn78/s320/10527_127356286546_506556546_2538898_1506419_n.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Modelling has been the most interesting part, rather than using a 3D modelling tool, I decided to generate it all in code using helper primitive classes, which handle drawing cubes and pyramids of differenet skews.&lt;br /&gt;&lt;br /&gt;Lighting comes free with OpenGL, so that was easy to set up, still need to provide better normals for the models, but will work on that later.&lt;br /&gt;&lt;br /&gt;I decided to go for a cartoon styled look by drawing lines around the edges of the primitives, had some issues with z fighting depending on the thickness of the lines, but instead of battling with it, I went with a line thickness that just worked.&lt;br /&gt;&lt;br /&gt;Animations was fun, I hooked in a model/primitive heichreichy and created a simple controller class to handle interpolating between frames. So when the character starts running, I just pass in the rotations that I want to occur and interpolate between them using the running speed, and the controller class handles the interpolation of all the rotations for all the frames. Next challenge will be prioiritising animations, so say when doing a shooting animation while running, the shooting animation will override the arm parts of the general running animation.&lt;br /&gt;&lt;br /&gt;But for now, I have a basic character on the screen that can run around, so the next step is tying in basic collisions so he has a world he can interact with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-4555062878870323328?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/4555062878870323328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/09/iphone-it-been-one-week.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4555062878870323328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4555062878870323328'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/09/iphone-it-been-one-week.html' title='iPhone - It&amp;#39;s been one week'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_6gAcZl1znWE/SqfGhS-kzBI/AAAAAAAAAAM/sXhWlQ0Fn78/s72-c/10527_127356286546_506556546_2538898_1506419_n.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-3882383474315610168</id><published>2009-09-09T16:10:00.000+01:00</published><updated>2011-03-26T03:00:02.488Z</updated><title type='text'>iPhone - Week One</title><content type='html'>Spent the last week working on modelling, lighting, cartoon rendering and animations.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I now have a basic character on the screen that can run around. Next step is tying in more objects and colliding them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-3882383474315610168?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/3882383474315610168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/09/iphone-week-one.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3882383474315610168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3882383474315610168'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/09/iphone-week-one.html' title='iPhone - Week One'/><author><name>Ash Cairo</name><uri>https://profiles.google.com/109880546681339859136</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-SZUQAA8CP5w/AAAAAAAAAAI/AAAAAAAAAFQ/u63CljthmX4/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-5422325113307286437</id><published>2009-08-30T23:41:00.000+01:00</published><updated>2011-03-26T03:00:02.490Z</updated><title type='text'>iPhone - Project Malaks</title><content type='html'>Last week I finally got round to purchasing a macbook air, so now I have the chance to jump in and do some iphone programming.&lt;br /&gt;&lt;br /&gt;After spending about a week orienting myself to the new environment, OS X and xcode, I started working on creating a 3d game engine. So far it's early stages, implementing simple engine code to handle 3D third person camera and object movement. ( I'll try to post a video soon )&lt;br /&gt;&lt;br /&gt;The plan is to have something presentable by the end of the year, I'll try to keep you posted with how the engine delopment goes regulary inbetween code thrashing sessions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-5422325113307286437?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/5422325113307286437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/08/iphone-project-malaks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5422325113307286437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5422325113307286437'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/08/iphone-project-malaks.html' title='iPhone - Project Malaks'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-7706210789020206779</id><published>2009-08-01T15:08:00.006+01:00</published><updated>2009-08-01T15:21:39.152+01:00</updated><title type='text'>Mortgage Calculator</title><content type='html'>Just came back from holiday and remembered that the &lt;a href="http://www.mortgageloanplace.com/mortgage-calculator.php" target="_blank"&gt;"Super Sexy" Mortgage Calculator Contest&lt;/a&gt; was coming to a close. So I quickly knocked up an entry.&lt;br /&gt;&lt;br /&gt;Check it out at &lt;a href="http://igrapher.com/iMortgage" target="_blank"&gt;http://igrapher.com/iMortgage&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There's lot's of features I'd still like to implement, but for 15 hours work over 3 days, I'm content with the outcome. Positive things about this calculator is that it doesn't use flash (so the charts work on mobiles), and does all the calculations asynchronously client side, so there's no wasted server interactions. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-7706210789020206779?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/7706210789020206779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/08/mortgage-calculator.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7706210789020206779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7706210789020206779'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/08/mortgage-calculator.html' title='Mortgage Calculator'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-3892102040189456813</id><published>2009-07-14T20:41:00.001+01:00</published><updated>2009-07-14T20:42:55.836+01:00</updated><title type='text'>v1.93 News platform demo</title><content type='html'>Hey, just finished implementing the stock headlines feature. Just double click on the graph and the headlines for the stock graphed on the date hovered will be displayed.&lt;br /&gt;&lt;br /&gt;Here's a quick video demonstrating how to use it. Enjoy.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/1GvXwGm295Q&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/1GvXwGm295Q&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-3892102040189456813?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/3892102040189456813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/07/v193-news-platform-demo.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3892102040189456813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3892102040189456813'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/07/v193-news-platform-demo.html' title='v1.93 News platform demo'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-7137669595762338295</id><published>2009-07-02T14:12:00.005+01:00</published><updated>2009-07-02T14:19:40.975+01:00</updated><title type='text'>News Aggregation Update</title><content type='html'>Just a quick update on the progress of the news platform development. Currently we're working on aggregating more news sources together into the new news headlines table.&lt;br /&gt;&lt;br /&gt;We're also looking to display the news graphed from the scan news activity feature. Meaning that soon you'll beable to graph a stock, then double click on a date, and the news for the stock released on that date will be displayed in the headlines table.&lt;br /&gt;&lt;br /&gt;We've also started work on porting this engine to scan and chart sports news and data. This will make our engine more portable to meet our long term goal of providing an API, for our users to scan and chart their own news/data feeds.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-7137669595762338295?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/7137669595762338295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/07/news-aggregation-update.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7137669595762338295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7137669595762338295'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/07/news-aggregation-update.html' title='News Aggregation Update'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-2510747876297329760</id><published>2009-06-16T02:53:00.002+01:00</published><updated>2009-06-16T03:05:24.932+01:00</updated><title type='text'>v1.9 News Feed</title><content type='html'>The main new feature in this release is the first first step towards the new news aggregation plaform. For the moment you should notice a simple bar at the bottom of the charts displaying the latest news headlines. Coming soon will be the rest of the framework, which'll allow you to expand the news bar to see the relevant stories. As well as be able to see the news headlines of the charts as you're scrolling through the dates.&lt;br /&gt;&lt;br /&gt;Also in this version, we've put in a lot of under the hood work in the form refactoring and optimising the engine, with a lot of niggly bugs being fixed along the way. So now it should be more dynamic and extensible from a development point of view.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-2510747876297329760?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/2510747876297329760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/06/v19-news-feed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/2510747876297329760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/2510747876297329760'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/06/v19-news-feed.html' title='v1.9 News Feed'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-2778829814930062461</id><published>2009-05-30T14:17:00.008+01:00</published><updated>2009-05-30T14:41:05.380+01:00</updated><title type='text'>Chart Stock News Activity</title><content type='html'>Ever wanted to chart the news activity for a stock? Well, now you can.&lt;br /&gt;&lt;br /&gt;To try this feature out, simply select a stock from the right menu, then click the legend button on the top left after the stock's graph displays, then select the Scan News Activity button.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_z75fiuW5_aI/SiE1jjahKiI/AAAAAAAAACk/pmufU2Hyp-c/s1600-h/ScreenShot001.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 191px;" src="http://3.bp.blogspot.com/_z75fiuW5_aI/SiE1jjahKiI/AAAAAAAAACk/pmufU2Hyp-c/s320/ScreenShot001.png" alt="" id="BLOGGER_PHOTO_ID_5341609517956278818" border="0" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_z75fiuW5_aI/SiE1qIzpERI/AAAAAAAAACs/uT0tEG69ITU/s1600-h/ScreenShot002.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 191px;" src="http://1.bp.blogspot.com/_z75fiuW5_aI/SiE1qIzpERI/AAAAAAAAACs/uT0tEG69ITU/s320/ScreenShot002.png" alt="" id="BLOGGER_PHOTO_ID_5341609631072981266" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe name="iGrapher" src="http://igrapher.com/index_iframe.php?#iframe?1;intro?0;resizer?0;m?0:9;stock?DJI:DJI;news?DJI:DJI:NEWS;b?USD;z?5;" marginwidth="0" marginheight="0" scrolling="no" width="600" frameborder="1" height="350"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;We honestly don't know how useful this feature will become, but I imagine it'll has a lot of potential.&lt;br /&gt;&lt;br /&gt;Next, we're going to be actually displaying the news that's charted on the graph, so you can easily jump to a particular date and see the news headlines with links to the actual articles. Further ahead, we'll be including more news sources and parsing the news data to judge the bias of the author of an article and how relevant it was to the stock's movement. Watch this space.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-2778829814930062461?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/2778829814930062461/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/05/news-activity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/2778829814930062461'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/2778829814930062461'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/05/news-activity.html' title='Chart Stock News Activity'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_z75fiuW5_aI/SiE1jjahKiI/AAAAAAAAACk/pmufU2Hyp-c/s72-c/ScreenShot001.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-2026748532832183897</id><published>2009-05-16T21:25:00.003+01:00</published><updated>2009-05-16T21:27:25.911+01:00</updated><title type='text'>Swiss SMI Market</title><content type='html'>Just finished updating the new market selection menus. Split the markets up into continental regions so we can fit in more markets per region. Added the Swiss SMI market into the European category.&lt;br /&gt;&lt;br /&gt;&lt;iframe name="iGrapher" src="http://igrapher.com/index_iframe.php?#iframe?1;intro?0;resizer?0;stock?SSMI:SSMI;b?CHF;m?0:2;" frameborder="1" width="600" height="350" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Since we have more space, we're going to start charting a lot more markets very soon.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-2026748532832183897?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/2026748532832183897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/05/swiss-smi-market.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/2026748532832183897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/2026748532832183897'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/05/swiss-smi-market.html' title='Swiss SMI Market'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-8266025559957409666</id><published>2009-05-13T05:34:00.001+01:00</published><updated>2009-05-13T05:40:44.476+01:00</updated><title type='text'>Forex Trend Shift Analysis and Predictions</title><content type='html'>Going on a big drive at the moment to get more and more features in. The latest addition to the engine giving the ability to run the trend shift analysis and predictions on currency market data. We're going to be adding in some more algorithms in the near future, so watch this space. In the mean time, here's an example of it running for the Yen.&lt;br /&gt;&lt;br /&gt;&lt;iframe name="iGrapher" src="http://igrapher.com/index_iframe.php?#iframe?1;intro?0;resizer?0;m?1:0;c?JPY:GBP:FX;z?13;predict?03-Dec-08:09-May-09:JPY:GBP:FX;" frameborder="1" width="600" height="350" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Remember, to run analysis and predictions of your own, simple click the graph legend button on the top left, then select Analyse Trend Shifts from the menu that appears.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-8266025559957409666?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/8266025559957409666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/05/forex-trend-shift-analysis-and.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8266025559957409666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8266025559957409666'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/05/forex-trend-shift-analysis-and.html' title='Forex Trend Shift Analysis and Predictions'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-5688687272198859356</id><published>2009-05-10T04:53:00.000+01:00</published><updated>2009-05-12T04:34:46.605+01:00</updated><title type='text'>National Stock Exchange of India Graphed</title><content type='html'>Just implemented the national stock exchange of India and the US S&amp;P 500 markets, so you can have a play with those markets too now. Also patched a few bugs here and there mainly to do with conversion rates. Next will be to split up the different markets into regions as well as get the lastest price data pumping for the Egyptian and Indian stock markets.&lt;br /&gt;&lt;br /&gt;Have a play.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;iframe name="iGrapher" src="http://igrapher.com/index_iframe.php?#iframe?1;intro?0;resizer?0;stock?NSEI:NSEI;b?INR;" frameborder="1" width="400" height="250" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt; &lt;iframe name="iGrapher2" src="http://igrapher.com/index_iframe.php?#iframe?1;intro?0;resizer?0;b?USD;stock?GSPC:GSPC;" frameborder="1" width="400" height="250" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;&lt;br /&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-5688687272198859356?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/5688687272198859356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/05/national-stock-exchange-of-india.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5688687272198859356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5688687272198859356'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/05/national-stock-exchange-of-india.html' title='National Stock Exchange of India Graphed'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-1884169411062824941</id><published>2009-05-09T13:43:00.004+01:00</published><updated>2009-07-14T19:05:37.240+01:00</updated><title type='text'>Egyptian Stock Markets</title><content type='html'>Just finished implementing the egyptian stock markets into iGrapher. Still have to feed in the latest stock movements as they occur during the day, but all the history data is now live. Going to fix up a few bugs next before implementing the latest movement and more markets.&lt;br /&gt;&lt;br /&gt;Have a play.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;iframe name="iGrapher" src="http://igrapher.com/index_iframe.php?#iframe?1;intro?0;resizer?0;stock?EGX30:EGX30;stock?EGX70:EGX70;z?29;b?EGP;m?0:11;" frameborder="0" width="500" height="300" marginwidth="0" marginheight="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;&lt;br /&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-1884169411062824941?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/1884169411062824941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/05/egyptian-stock-markets.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1884169411062824941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1884169411062824941'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/05/egyptian-stock-markets.html' title='Egyptian Stock Markets'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-6958522200708168581</id><published>2009-05-04T13:30:00.000+01:00</published><updated>2009-05-04T13:37:29.142+01:00</updated><title type='text'>Reddit love</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_z75fiuW5_aI/Sf7g3jMqGJI/AAAAAAAAACc/0Jv26MbT7QA/s1600-h/iGrapher+-+RedditFame.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 191px;" src="http://1.bp.blogspot.com/_z75fiuW5_aI/Sf7g3jMqGJI/AAAAAAAAACc/0Jv26MbT7QA/s320/iGrapher+-+RedditFame.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5331946253799004306" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;iGrapher was recently featured on one of the posts in the programming section of Reddit and recieved a lot of community support. In fact, at the peak we recieved over 65,000 hits. One of the most highly suggested improvements was support for more markets. So that's what's currently in development. Feel free to suggest any particular markets you'd like to see added.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-6958522200708168581?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/6958522200708168581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/05/reddit-love.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6958522200708168581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6958522200708168581'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/05/reddit-love.html' title='Reddit love'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_z75fiuW5_aI/Sf7g3jMqGJI/AAAAAAAAACc/0Jv26MbT7QA/s72-c/iGrapher+-+RedditFame.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-1492140239242117204</id><published>2009-04-02T04:33:00.000+01:00</published><updated>2009-04-02T04:47:21.699+01:00</updated><title type='text'>3D Visualisations in the works</title><content type='html'>Just a little update on what's going on, after releasing the trend shifts analysis platform for iGrapher, our focus shifted towards bug fixing and solidifying the platform we've built up.&lt;br /&gt;&lt;br /&gt;In the mean time we started development on a side project engine to render 3D polygons fast inside a web browser. The plan is to get it running as fast as possible so we can have 3D graphics in a web browser on the iPhone.&lt;br /&gt;&lt;br /&gt;After having success on the initial proof of concept work, we're aiming to have a robust plug-able engine demonstrable very soon.&lt;br /&gt;&lt;br /&gt;Here's a video of the initial proof of concept work.&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/aa03ObBtKrg&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/aa03ObBtKrg&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Music provided by AndyT - Wagons Roll.&lt;br /&gt;&lt;br /&gt;So hopefully soon, you'll be seeing 3D visualisations popping up in the near future.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-1492140239242117204?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/1492140239242117204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/04/3d-visualisations-in-works.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1492140239242117204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1492140239242117204'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/04/3d-visualisations-in-works.html' title='3D Visualisations in the works'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-7886168092863773958</id><published>2009-03-22T00:14:00.000Z</published><updated>2009-03-22T00:18:14.069Z</updated><title type='text'>v1.71 iPhone Creature Feature</title><content type='html'>Just finished porting the trend shifts platform over to the iPhone. I've also compiled a quick features usage video to help demonstrate how to use the software.&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/BeilHKQojio&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/BeilHKQojio&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Music provided by AndyT - Creature Feature.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-7886168092863773958?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/7886168092863773958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/03/v171-iphone-trends-parity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7886168092863773958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/7886168092863773958'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/03/v171-iphone-trends-parity.html' title='v1.71 iPhone Creature Feature'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-6505583256197411571</id><published>2009-03-20T04:53:00.001Z</published><updated>2009-03-20T18:58:55.196Z</updated><title type='text'>v1.7 Trend Shifts Implemented</title><content type='html'>We just released the intial implementation of the trend shifts analysis and prediction tools, it works pretty well. I've quickly mocked up a video demonstration on how to use the new tools, just in case it's not so obvious.&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="295"&gt;&lt;param name="movie" value="http://www.youtube.com/v/25xtNmt9Azc&amp;hl=en&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/25xtNmt9Azc&amp;hl=en&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Next up, we have to port it over for use on the iPhone, enable it to work off forex data (only minor tweaks required), and then go ahead and put in some more complicated trend analysis, for example as discussed before, differentiating between major/minor trends.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-6505583256197411571?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/6505583256197411571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/03/v17-trend-shifts-implemented.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6505583256197411571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6505583256197411571'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/03/v17-trend-shifts-implemented.html' title='v1.7 Trend Shifts Implemented'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-5580118090711096004</id><published>2009-03-08T18:07:00.000Z</published><updated>2009-03-20T04:59:05.147Z</updated><title type='text'>Prediciton platform coming soon in v1.7</title><content type='html'>We have finally reached a stage where we can now work towards a providing various analysis and prediction algorithms. The first batch of tasks have been designed and are now in development.&lt;br /&gt;&lt;br /&gt;So, in the next release you'll have the ability to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Draw graphs based on the shifts in price momentum.&lt;/li&gt;&lt;li&gt;Get statistics on how often the price momentum shifts weekly, monthly, yearly breakdowns.&lt;/li&gt;&lt;li&gt;Distinguish between the types of shifts occurring (major/minor).&lt;/li&gt;&lt;li&gt;Estimate the type of the current shift currently occurring and how long it's expected to last.&lt;/li&gt;&lt;/ul&gt;It's basic analysis, however it'll be a great first step towards a more dynamic analysis tool.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-5580118090711096004?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/5580118090711096004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/03/prediciton-platform-coming-soon-in-v17.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5580118090711096004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/5580118090711096004'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/03/prediciton-platform-coming-soon-in-v17.html' title='Prediciton platform coming soon in v1.7'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-3210236877169364452</id><published>2009-03-02T03:17:00.000Z</published><updated>2009-03-08T18:33:10.656Z</updated><title type='text'>Hacking the Heart</title><content type='html'>&lt;b&gt;"If open bracket love equal equals true, my heart's pointer is forever assigned to you"&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;The only way to be forever assigned to someone, is by using a const pointer. So say we had a heart inside of us..&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Heart&lt;br /&gt;{&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Us&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;Us()&lt;br /&gt;{&lt;br /&gt; myHeart = new Heart();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;~Us()&lt;br /&gt;{&lt;br /&gt; delete myHeart;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;const Heart* GetConstHeartPtr()&lt;br /&gt;{&lt;br /&gt; return myHeart;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;Heart* myHeart;&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In our main function in order to hack the heart, since our hearts are constant, there would be no legal way to change it. Unless we malloced over our heart with their heart.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;Us *me = new Us();&lt;br /&gt;Us *you = new Us();&lt;br /&gt;&lt;br /&gt;if( me != NULL &amp;amp;&amp;amp; you != NULL )&lt;br /&gt;{&lt;br /&gt; memcpy( me, you, sizeof( Heart ) );&lt;br /&gt;&lt;br /&gt; if( me-&gt;GetConstHeartPtr() == you-&gt;GetConstHeartPtr() )&lt;br /&gt; {&lt;br /&gt;  printf( "Love" );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hacky but, it still doesn't work. Why? Because our hearts are empty. However, if we go back to the start and fill our hearts with something.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Heart&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;     Heart(const char *name)&lt;br /&gt;           : name( name )&lt;br /&gt;     {}&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;     const char *name;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;class Us&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;Us(const char *name)&lt;br /&gt;{&lt;br /&gt; myHeart = new Heart( name );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;~Us()&lt;br /&gt;{&lt;br /&gt; delete myHeart;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;const Heart* GetConstHeartPtr()&lt;br /&gt;{&lt;br /&gt; return myHeart;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;Heart* myHeart;&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We'd now have something to allocate, because our heart would point to a memory location which contains a name, which can be copied using malloc and filled.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;Us *me = new Us( "ash" );&lt;br /&gt;Us *you = new Us( "you" );&lt;br /&gt;&lt;br /&gt;if( me != NULL &amp;amp;&amp;amp; you != NULL )&lt;br /&gt;{&lt;br /&gt; memcpy( me, you, sizeof( Heart ) );&lt;br /&gt;&lt;br /&gt; if( me-&gt;GetConstHeartPtr() == you-&gt;GetConstHeartPtr() )&lt;br /&gt; {&lt;br /&gt;  printf( "Love" );&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So what's the lesson to be learned?&lt;br /&gt;Don't try to love a girl that's &lt;b&gt;heartless&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_z75fiuW5_aI/SatQD2H9TMI/AAAAAAAAAB0/oPvieqVgZBY/s1600-h/ScreenShot001.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 159px;" src="http://2.bp.blogspot.com/_z75fiuW5_aI/SatQD2H9TMI/AAAAAAAAAB0/oPvieqVgZBY/s320/ScreenShot001.png" alt="" id="BLOGGER_PHOTO_ID_5308424612784983234" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-3210236877169364452?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/3210236877169364452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/03/hacking-heart.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3210236877169364452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3210236877169364452'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/03/hacking-heart.html' title='Hacking the Heart'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_z75fiuW5_aI/SatQD2H9TMI/AAAAAAAAAB0/oPvieqVgZBY/s72-c/ScreenShot001.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-4190882785102688787</id><published>2009-02-26T14:19:00.000Z</published><updated>2009-03-08T18:28:48.135Z</updated><title type='text'>Price Scanning With HTML Tables</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_z75fiuW5_aI/SabUTc_jIRI/AAAAAAAAABs/xs2o9wv9wEw/s1600-h/ScreenShot002.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 187px;" src="http://1.bp.blogspot.com/_z75fiuW5_aI/SabUTc_jIRI/AAAAAAAAABs/xs2o9wv9wEw/s320/ScreenShot002.png" alt="" id="BLOGGER_PHOTO_ID_5307162641568047378" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;"&gt;In the next release&lt;/span&gt; of iGrapher the main new feature will be a much needed hovering price scanner. So as you scroll over the chart, it'll give you an indication of the price of the stock on that date, as seen in the image above.&lt;br /&gt;&lt;br /&gt;To implement this we would need to create a table the size of a point, colour it, then moved it along the position of the mouse while over the graph.&lt;br /&gt;&lt;br /&gt;So we first create a class to encapsulate the scanners function so we can easily iterate it's functionality over as many stocks currently drawn on the graph.&lt;br /&gt;&lt;br /&gt;&lt;table style="border: 1px solid rgb(153, 153, 181); font-size: 90%;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;function PriceScanner(index)&lt;br /&gt;{&lt;br /&gt;this.table = document.createElement( 'table' );&lt;br /&gt;this.td = document.createElement( 'td' );&lt;br /&gt;this.border = "4px solid " + graphColours[index];&lt;br /&gt;&lt;br /&gt;this.table.cellPadding = 0;&lt;br /&gt;this.table.cellSpacing = 0;&lt;br /&gt;this.table.style.position = 'absolute';&lt;br /&gt;this.table.style.left = 1;&lt;br /&gt;this.table.style.top = 1;&lt;br /&gt;        &lt;br /&gt;var priceScannerTBody = document.createElement( 'tbody' );&lt;br /&gt;var priceScannerTR = document.createElement( 'tr' );&lt;br /&gt;&lt;br /&gt;this.table.appendChild( priceScannerTBody );&lt;br /&gt;priceScannerTBody.appendChild( priceScannerTR );&lt;br /&gt;priceScannerTR.appendChild( this.td );&lt;br /&gt;&lt;br /&gt;canvasParent.appendChild( this.table );&lt;br /&gt;}&lt;br /&gt;var priceScanners;&lt;/code&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Next in our mousemove event we run the scanner update function if it's over the graph canvas, after recording our mouse x and y coordinates.&lt;br /&gt;&lt;br /&gt;Then in our scanner update function for all the stocks drawn on the graph, we pick out the price index that's closest to the mouse coordinate, work out the draw point and set the table's left and top attributes to point to the same point. Then set the border of the table to be it's "this.border" property. When the mouse goes off the chart we stop calling the update function and the border back to "" so it disappears from our view.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;Also in the next release&lt;/span&gt; we've freshed up the design a little throwing in some outset tables and buttons, fixed a few niggly bugs todo with scrolling and resizing at unusual occasions and included the minute to minute data to the graph slider at the bottom, so when you slide it to the right it'll go to today's movements.&lt;br /&gt;&lt;a href="http://igrapher.com"&gt;&lt;br /&gt;iGrapher&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-4190882785102688787?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/4190882785102688787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/02/price-scanning-with-html-tables.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4190882785102688787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4190882785102688787'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/02/price-scanning-with-html-tables.html' title='Price Scanning With HTML Tables'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_z75fiuW5_aI/SabUTc_jIRI/AAAAAAAAABs/xs2o9wv9wEw/s72-c/ScreenShot002.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-8395311732331537795</id><published>2009-02-06T15:10:00.000Z</published><updated>2009-03-08T18:29:40.117Z</updated><title type='text'>From x to i</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_z75fiuW5_aI/SYxZpP01kmI/AAAAAAAAABg/dFiKq6TPQKM/s1600-h/ScreenShot002.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 19px;" src="http://4.bp.blogspot.com/_z75fiuW5_aI/SYxZpP01kmI/AAAAAAAAABg/dFiKq6TPQKM/s320/ScreenShot002.png" alt="" id="BLOGGER_PHOTO_ID_5299709426665886306" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;A few days ago, when we tried logging into the ftp account to roll out a new update, we'd got a password incorrect error. We emailed the host, but there was no reply. Then we noticed that the site was gradually being re-branded... We'd been hijacked!&lt;br /&gt;&lt;br /&gt;The thing is, since we started this project as a self-development exercise to extend our knowledge on the financial sector. We never actually considered it branching out and becoming popular (at least so soon). But, ever since we gained recognition on the internets (mostly thanks to apple), we immediately began being targeted for a takeover.&lt;br /&gt;&lt;br /&gt;We still saw this project as in it's infancy, and refused to consider any offers. However, our web hosting company saw otherwise. Since it had let us use it's web space and domain for free (thanks), it also meant that they owned the legal rights to it. Well, on that day, they decided to hold us for ransom.&lt;br /&gt;&lt;br /&gt;So...&lt;br /&gt;&lt;br /&gt;Out with the old and in with the new? Development on this financial visualisation project will now continue on iGrapher.com, hope you like the name, it's very apple-centric, but, I guess it works.&lt;br /&gt;&lt;br /&gt;In our next update we'll be implementing history downloading optimisations and extending currency exchange history data.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-8395311732331537795?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/8395311732331537795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/02/from-x-to-i.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8395311732331537795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/8395311732331537795'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/02/from-x-to-i.html' title='From x to i'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_z75fiuW5_aI/SYxZpP01kmI/AAAAAAAAABg/dFiKq6TPQKM/s72-c/ScreenShot002.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-6872707079619007401</id><published>2009-01-29T20:26:00.002Z</published><updated>2011-03-27T07:18:38.890+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='igrapher'/><category scheme='http://www.blogger.com/atom/ns#' term='cute'/><title type='text'>RBS ♥ You</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_z75fiuW5_aI/SYITYmY-uzI/AAAAAAAAAA0/CDmi17V0gkg/s1600-h/ScreenShot003.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 176px;" src="http://1.bp.blogspot.com/_z75fiuW5_aI/SYITYmY-uzI/AAAAAAAAAA0/CDmi17V0gkg/s320/ScreenShot003.png" alt="" id="BLOGGER_PHOTO_ID_5296817425084234546" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;While looking through various charts, my friend noticed a cute little pattern in the graph for Royal Bank of Scotland's stock history.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;iframe name="iGrapher" src="http://igrapher.com/index_iframe.php#iframe?1;stock?RBS.L:FTSE;z?3;tmi?785;ix?565;date?30-Dec-08;resizer?0;" width="600" frameborder="1" height="400"&gt;&lt;/iframe&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;What does this mean? Well, it's conclusive proof that the Royal Bank of Scotland loves you... or that it's bragging about a new boob job? or quiet possibly that it's flashing you it's butt right before it's stock crashes?&lt;br /&gt;&lt;br /&gt;More mysteries coming as soon as I implement the cute shape stock matching algorithm.&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;&lt;br /&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-6872707079619007401?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/6872707079619007401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/01/rbs-you.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6872707079619007401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/6872707079619007401'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/01/rbs-you.html' title='RBS ♥ You'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_z75fiuW5_aI/SYITYmY-uzI/AAAAAAAAAA0/CDmi17V0gkg/s72-c/ScreenShot003.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-4019117956588315535</id><published>2009-01-28T00:06:00.000Z</published><updated>2009-03-08T18:29:47.567Z</updated><title type='text'>Streaming Javascript</title><content type='html'>One of my favourite features of Javascript is the ability to write more source code on the fly. Usually in most languages I've used before in the past, you'd have to write the code, compile it, link it, then run. In Javascript you can write source code which writes source code and runs it ON-THE-FLY.&lt;br /&gt;&lt;br /&gt;So for example I could do this in my code.&lt;br /&gt;&lt;br /&gt;&lt;table style="border: 1px solid rgb(153, 153, 181);"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;// Create a new script element&lt;br /&gt;var bamScript = document.createElement( 'script' );&lt;br /&gt;&lt;br /&gt;// Fill in the script element with more source code&lt;br /&gt;bamScript.text = 'function bam() { alert("aahh"); }';&lt;br /&gt;&lt;br /&gt;// Add our script to the document&lt;br /&gt;document.body.appendChild( bamScript );&lt;br /&gt;&lt;br /&gt;// Run our newly added script.&lt;br /&gt;bam();&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;This piece of code, would add in a new script element with a function called bam, which we can run right after it's added to our document. AMAZING!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;(Note: A few gotchas I came accross. Make sure you use the text parameter and not the innerHTML one. InnerHTML will work fine in Firefox, however in Internet Explorer it'll go boom, and on the iPhone's safari, it'll go boom depending on the complexity of the source code you're writing.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since the beginning of iGrapher I've been meaning to use this feature of Javascript, however with the use of gzip, my javascript has been small enough to avoid needed to split the program into separate downloadable components. However, since porting to the iPhone, I've found that it takes a good few seconds to load, so I finally pushed ahead the usage of self-writing source code.&lt;br /&gt;&lt;br /&gt;So now in v1.56 iGrapher will load in a small script which dynamically streams in more source code using the XMLHttpRequest object. At the moment the source code is split in two, however I plan on breaking it up into further components so at first the necessary components download first, then the non-essentials (top menu, data spanner, etc.)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_z75fiuW5_aI/SX-lq48-r8I/AAAAAAAAAAc/TBKqu1XClVo/s1600-h/ScreenShot002.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 312px; height: 164px;" src="http://3.bp.blogspot.com/_z75fiuW5_aI/SX-lq48-r8I/AAAAAAAAAAc/TBKqu1XClVo/s320/ScreenShot002.png" alt="" id="BLOGGER_PHOTO_ID_5296133843072233410" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-4019117956588315535?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/4019117956588315535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/01/streaming-javascript.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4019117956588315535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/4019117956588315535'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/01/streaming-javascript.html' title='Streaming Javascript'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_z75fiuW5_aI/SX-lq48-r8I/AAAAAAAAAAc/TBKqu1XClVo/s72-c/ScreenShot002.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-882576143117154643</id><published>2009-01-20T03:55:00.001Z</published><updated>2009-03-08T18:29:53.026Z</updated><title type='text'>My iPhone Gesture Dilemma</title><content type='html'>Currently in Safari, if you touch the screen with more than one finger, then rotate the phone. Safari will crash in a very perverse way.&lt;br /&gt;&lt;br /&gt;The program will still be on the screen however all javascript will not function, the status bar buttons will not function, and you will no longer &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;be able&lt;/span&gt; to navigate the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;Internet&lt;/span&gt;, it'll just hang.&lt;br /&gt;&lt;br /&gt;The only way around this state is to turn off the phone, then turn it back on.&lt;br /&gt;&lt;br /&gt;Now the problem is, I wanted to add the zooming feature to the graphs and I wanted it to make use of the famous pinch technique. Should I &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;disallow&lt;/span&gt; multi-touch gestures and use a different technique or just allow pinching in hope no one would rotate their phone?&lt;br /&gt;&lt;br /&gt;I decided to allow pinching, but display a warning message, informing the user that if they rotated their phone, it will go boom!&lt;br /&gt;&lt;br /&gt;Sigh..&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_z75fiuW5_aI/SXVN_CqsUNI/AAAAAAAAAAU/_lb2znpJpfI/s1600-h/ScreenShot001.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 302px; height: 191px;" src="http://4.bp.blogspot.com/_z75fiuW5_aI/SXVN_CqsUNI/AAAAAAAAAAU/_lb2znpJpfI/s320/ScreenShot001.png" alt="" id="BLOGGER_PHOTO_ID_5293222682486919378" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-882576143117154643?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/882576143117154643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/01/my-iphone-gesture-dilemma.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/882576143117154643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/882576143117154643'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/01/my-iphone-gesture-dilemma.html' title='My iPhone Gesture Dilemma'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_z75fiuW5_aI/SXVN_CqsUNI/AAAAAAAAAAU/_lb2znpJpfI/s72-c/ScreenShot001.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-3787158762038931122</id><published>2009-01-19T19:27:00.000Z</published><updated>2009-03-08T18:31:42.893Z</updated><title type='text'>iPhone v1.5 Preview</title><content type='html'>Work on the iPhone version of iGrapher has been on-going all week and we have hit a few milestones this past weekend. The shares menu is much more usable, XML has been ditched for a custom .xg format which is half the size of XML meaning faster data downloads and work on scrolling the graph canvas has started.&lt;br /&gt;&lt;br /&gt;Here's a little preview of the iPhone version in action.&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ma5sfdiApzc&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/ma5sfdiApzc&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-3787158762038931122?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/3787158762038931122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/01/iphone-v72-preview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3787158762038931122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/3787158762038931122'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/01/iphone-v72-preview.html' title='iPhone v1.5 Preview'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-1655548354890788008</id><published>2009-01-16T05:55:00.000Z</published><updated>2009-03-08T18:31:00.560Z</updated><title type='text'>My iPhone Web App Experience</title><content type='html'>So I submitted my grapher program to the apple web app directory the other day. Not expecting much of it, I decided to give it a little test run to make sure it all still worked. I had been making sure it functioned on the iPhone, feature by feature as I implemented them on the desktop, however I had never actually tried using it from an end-users point to view.&lt;br /&gt;&lt;br /&gt;Needless to say, it was too buggy, with several crashes and annoyances. I wasn't happy! I frantically spent the night fixing bug after bug. The clock hit 4:30am and I had patched it up enough for it to be barely functional.&lt;br /&gt;&lt;br /&gt;You couldn't scroll the charts, but at least you could just about click on some buttons without it reacting erratically and be able to rotate the phone, without it crashing.&lt;br /&gt;&lt;br /&gt;I uploaded the new version, then checked my e-mail to find a welcome note from apple. So I figured I'd check their web directory...&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_z75fiuW5_aI/SXAiUTAdEWI/AAAAAAAAAAM/cN5GD_U-mgw/s1600-h/Apple+Web+Apps+-+xGrapher.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 318px; height: 320px;" src="http://1.bp.blogspot.com/_z75fiuW5_aI/SXAiUTAdEWI/AAAAAAAAAAM/cN5GD_U-mgw/s320/Apple+Web+Apps+-+xGrapher.png" alt="" id="BLOGGER_PHOTO_ID_5291767294255239522" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Woah... Featured with a staff pick. I have no idea how!?&lt;br /&gt;&lt;br /&gt;I was pretty sure, I'd get rejected with perhaps some useful advice on how to improve the app, but wow!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The worst problems faced when porting to the iPhone?&lt;/span&gt;&lt;br /&gt;Viewport - Don't experiment with different width's and height's, when you do so, it randomly jumps from dimension to dimension when rotating.&lt;br /&gt;I found it best for me to set the scale to be 1.0 for all the scale options..&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;content="minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So I could always have the same dimension when rotating.&lt;br /&gt;&lt;br /&gt;Multi-touch - It's strange this one, if you use a multi-touch gesture (very very fun to do so) and rotate the iPhone at the same time, it goes boom! I tried every permutation possible to get round this issue, but I found it crashes regular websites, and it doesn't just crash in a close down safari friendly way. It keeps Safari running, however the internet becomes unusable, it just hangs forever trying to connect to a website. The only way I found around it was to turn off the phone then turn it back on again. My coding solution was to override the gesturestart event, then fire off an alert if the user tried using multi-touch. I'm defiantly not happy with this, but it's the only way I could get round this issue. Maybe it's just my phone, I'll have to look more into this. Would be nice to hear if anyone else has experienced this?&lt;br /&gt;&lt;br /&gt;OnResize - On a desktop PC, by default I had used the onresize event to inform me when I needed to resize my grapher to fit the screen. On the iPhone... BIG MISTAKE! It kept firing the onresize event randomly and relentlessly (probably because my viewport size wasn't set as advised above). However, once I found out that this was the cause of my app crashing, I simply switched over to &lt;span style="font-style: italic;"&gt;orientationchange&lt;/span&gt; for the iPhone. That event would fire (as long as you never had two fingers on the screen) and you could get the viewport rotation from the window.orientation variable.&lt;br /&gt;&lt;br /&gt;Adsense - A quick final tip for adsense users. I'm not a fan of irritating in your face adverts, so I specifically had only used a 468x15 text ad for the non-iPhone version. However, because of the viewport size limitation, I had to switch over to the next smallest thing for the iPhone.&lt;br /&gt;&lt;br /&gt;To get a different advert on a different device for the same page, I had originally tried asking google for what to do. However, no one ever got back to me, so I came to the realisation that php was my friend.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;[?php&lt;br /&gt; $ua = $_SERVER['HTTP_USER_AGENT'];&lt;br /&gt; if( strpos( $ua, 'iPhone' ) == false )&lt;br /&gt; {&lt;br /&gt;echo '&lt;br /&gt;DESKTOP CODE&lt;br /&gt;';&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;echo '&lt;br /&gt;iPHONE CODE&lt;br /&gt;';&lt;br /&gt; }&lt;br /&gt;php?&lt;/span&gt;]&lt;br /&gt;&lt;br /&gt;Simple huh?&lt;br /&gt;&lt;br /&gt;We'll anyway, I'll try coming back here to post some more tips later, but it's 6am here and my alarm clocks going off.&lt;br /&gt;&lt;br /&gt;Thanks for reading.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-1655548354890788008?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/1655548354890788008/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/01/my-iphone-web-app-experience.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1655548354890788008'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1655548354890788008'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/01/my-iphone-web-app-experience.html' title='My iPhone Web App Experience'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_z75fiuW5_aI/SXAiUTAdEWI/AAAAAAAAAAM/cN5GD_U-mgw/s72-c/Apple+Web+Apps+-+xGrapher.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9133592462062635926.post-1584991580717797406</id><published>2009-01-02T07:20:00.000Z</published><updated>2009-05-13T05:34:02.149+01:00</updated><title type='text'>Turnaround for the pound?</title><content type='html'>Analysts have been prediciting the EURO to ascend to the heights of £1.50 per EURO within 6 months. However looking at the latest trades, has the rally for the EURO come to an end?&lt;br /&gt;&lt;br /&gt;&lt;iframe name="iGrapher" src="http://igrapher.com/index_iframe.php#c?GBP:EUR:FX;c?GBP:USD:FX;z?8;intro?0;resizer?0;b?USD;ix?36;date?01-Jan-09;" width="600" frameborder="1" height="400"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://igrapher.com/"&gt;iGrapher&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9133592462062635926-1584991580717797406?l=blog.softpoetry.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.softpoetry.com/feeds/1584991580717797406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.softpoetry.com/2009/01/turnaround-for-pound.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1584991580717797406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9133592462062635926/posts/default/1584991580717797406'/><link rel='alternate' type='text/html' href='http://blog.softpoetry.com/2009/01/turnaround-for-pound.html' title='Turnaround for the pound?'/><author><name>Cairo</name><uri>http://www.blogger.com/profile/06167546978111496513</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_z75fiuW5_aI/SzhIBXVHZ9I/AAAAAAAAAI0/q45dl8B5Kl4/S220/I%27m+Sorry+I+Love+You.jpg'/></author><thr:total>0</thr:total></entry></feed>
