Tuesday, June 30, 2009

Crosstown Traffic

Youre just like crosstown traffic
So hard to get through to you
Crosstown traffic
I dont need to run over you
Crosstown traffic
All you do is slow me down
And Im tryin to get on the other side of town
-Jimi Hendrix (The Master)

Actually, I'm no longer slowed down. I just got the cross-project building working. Hold on, here it comes...WHOOOHOOOO! Okay, it was pretty simple, and actually better than how I've done it on the PC/Visual Studio.

The cross project settings in XCode make it so that you can build static library projects, and link them to your main App project. The great thing is that you don't have to worry about the flavor of the build, i.e., iPhone debug/release Simulator, iPhone debug/release Device, iPhone debug/release 2.0, 3.0, 3.1, etc... You don't have to worry about getting the proper build libraries building with the proper App build settings.

The cross project settings handle it all for you. I read through the XCode Build Management documentation like I said I would, and it wasn't very clear, but I did find this tutorial that got me setup and running, so instead of regurgitating what I read, here's the link I followed...

http://blog.csdn.net/dotphoenix/archive/2009/05/16/4191455.aspx

However, in my journey of reading the docs I did run across a feature of XCode, "snapshotting," that works like a mini repository backup. So, if you don't have a SCM (source control manager) setup, or TimeMachine running, you should probably take a look at "snapshots."

Now, to the LuaBind build steps I promised in my last posting. Some asked, "how did you do it?" Now, without further ado, the steps...

1) Download Luabind 0.8.1 from here: http://mac.softpedia.com/progDownload/Luabind-Download-52705.html

2) Download Lua 5.1.2 from www.lua.org (LuaBind 0.8.1 currently only works with Lua 5.1.2).

3) Download Boost 1.39.0 from www.boost.org

4) Extract the above downloads to your desktop or some other area.

5) Create a Mac OS static library XCode project named "Lua...the following is from an earlier posting of mine that detailed how to build Lua. I will italicize so that the step numbers do not become confusing.

a) Get lua-5.1.2(Xcode).zip


b) Unzip it


c) It will unzip to the folder lua-5.1.2



d) Open it and double click on the lua.xcodeproj



e) Build the project (just to make sure it builds) ...it will generate a library file.



6) Now, create a Mac OS static library XCode project named "LuaBindLib."

7) From the extracted LuaBind download folder copy the LuaBind folder to the project's folder.

8) From the extracted LuaBind download folder copy the Src folder to the project's folder.

9) From the extracted Boost download folder copy the Boost folder to the project's folder.

10) In the LuaBindLib project folder create a folder name "Lua."

11) In the just created Lua folder, create a folder name, "Include."

12) From your earlier built Lua project find the following header files,

luaxlib.h
lau.h
lauconf.h
lualib.h

Copy them to the LuaBind\Lua\Include folder.

13) Your LuaBindLib folder should look like this...

LuaBindLib\
\LuaBind
\Src
\Boost
\Lua\Include

14) Add the Src folder to the project.

15) Bring up the "info," project window and go to the "Search Paths," section. On the "Header Search Paths," set the paths to the LuaBind, Boost, and Lua\Include folders.

16) Build and good luck. Leave a comment if you have any problems and would like some help.

To wrap up. Now, that I have the cross project library stuff working, I can get on with building my components as static libraries now. One more time...WHOOOHOOOO!!

Missed It

I was to attend the local iPhone/Android Meetup this evening, but had to miss it. The artist working with me on the game was in town this weekend, and leaving (ahhh...now this morning) today. We missed hooking up over the weekend so had to meet Monday night, thus I couldn't attend.

I was asked by more than one person to detail how I got LuaBind to work on the Mac/iPhone since there *are* some problems building for the Mac. So, in my next posting, not now, I'm tired, I will put down the steps that got LuaBind to work for me as a static library.

Until the next posting, happy coding. :)

Wednesday, June 24, 2009

Errata and What I'm Doing Now

In an earlier post I showed how to add to your $PATH. I actually typed it incorrectly, here is the correct way...

PATH=$PATH:/your path here
export PATH

Tonight/Today is one of those days where I take a step back, in hopes of being able to work smarter and faster in the long wrong. I have started reading the XCode documentation so that I can learn how to do "cross-reference project." Since I am a relative stranger in the Mac/XCode environment, the things that come to me rote on the PC/Visual Studio, have me fumbling around on the Mac.

On the PC if I want to have separate projects that build libraries that other projects use, it is simple, all I have to do is set the build environment to build the library and output the library to some common folder. Then, in the other project, just link against the library(s). I don't like adding the libraries to the project settings since I want to be able to easily move from one build setup to another, so I do in the source file...

#pragma comment(lib, "some lib")

So far, I haven't been able to do so in XCode. Ignorance is the common force behind prejudice so, I'm taking the time to know XCode. I already love most things about it, and once I become more familiar I am sure there will be more love. Besides, "some of my best friends are XCode.," "XCode you aren't like the others, you are special," "XCode you don't smell like *they* said you did," etc....

I want to be able to build my core components as static libraries, tie them into a project and have the changes updated.

Back to reading...

Thursday, June 18, 2009

Fade In

Int. Home Office Evening

Middle age, man, sits hunched over computer keyboard, pecking away.

MAN (muttering whisper)
Guess I'll blog about Lua Script integration success.

We zoom into his blog...

Whoooohooo! The Lua scripting is tied in. I downloaded, and built LuaBind as a static library and tied the scripting into my engine. I wrote up some little test scripts and was able to bind C/C++ to Lua, and Lua to C/C++. LuaBind is great, it frees you up to do what you want to do and that is script. Not sit around writing LuaGlue functions so that you can script. I've said it before, I'm lazy and want my tools to be easy to use, and this one surely is.

I also went back to my messaging scheme and enhanced to do derivable messages. Now, I can derive base objects, and have the derive object class register for the messages it wishes to have, and let the base class handle any messages I want the base implementation of, or ignore entirely.

So, after a night of being pretty tired and my mind not working, I arose after a solid 4 hours of sleep and things came to my mind more clearly.

Tonight I will relax on the coding and read some things I want to read on design and continue designing my engine.

Fade out.

Wednesday, June 17, 2009

I Smell Another Journey Coming On

Rolling my own bindings for Lua isn't going to cut it. So, I'm going to use LuaBind or LuaPlus. My hunch is that they just don't have a package that I can easily install. :)

We'll see...as Slick Rick sang, "wish me luck, 'cause I'm scared and I'm nervous" (The Ruler Is Back...that's old school hip hop).

Tuesday, June 16, 2009

"What has God wrought?

Okay...so it isn't as dramatic as Morse sending out his first message over wire, but I've completed the messaging for my engine using Boost Signals2. All is working well.

That's it, that's the post...short and sweet. Okay, okay...here's a sample of the messaging setup using Boost::Signals2...


class ObjController
{
public:
ObjController() { printf("ObjController::ctor called.\n"); }
~ObjController() { printf("ObjController::dtor called.\n"); }


boost::signals2::connection RegisterHitMsg(const signalSend_type::slot_type &subscriber)
{
return m_SendHitMsg.connect(
subscriber);
}

boost::signals2::connection RegisterRenderMsg(const signalSend_type::slot_type &subscriber)
{
return m_SendRenderMsg.connect(subscriber);
}

boost::signals2::connection RegisterTestMsg(const signalSend_type::slot_type &subscriber)
{
return m_SendTestMsg.connect(subscriber);
}

void CheckCollision(short nID)
{
m_SendHitMsg(nID);
}

void RenderObjs(short nID)
{
m_SendRenderMsg(nID);
}

void TestMsg(short nID)
{
m_SendTestMsg(nID);
}

private:
signalSend_type m_SendHitMsg;
signalSend_type m_SendRenderMsg;
signalSend_type m_SendTestMsg;
};

class ObjA
{
public:
ObjA(ObjController& objCntrl, short nID) : m_objCntrl(objCntrl), m_nID(nID)
{
printf("ObjA::ctor called.\n");

m_connection = m_objCntrl.RegisterHitMsg(boost::bind(&ObjA::HandleCollision, this, _1));
m_connection2 = m_objCntrl.RegisterRenderMsg(boost::bind(&ObjA::RenderObjects, this, _1));
m_connection3= m_objCntrl.RegisterTestMsg(boost::bind(&ObjA::Test, this, _1));
}

~ObjA()
{
printf("ObjA::dtor called.\n");

m_connection.disconnect();
m_connection2.disconnect();
m_connection3.disconnect();
}

private:
void HandleCollision(short nID)
{
if(m_nID == nID || kBROADCAST == nID)
printf("ObjA::HandleCollision called - id: %d\n", m_nID);
}

void RenderObjects(short nID)
{
if(m_nID == nID || kBROADCAST == nID)
printf("ObjA::RenderObjects called - id: %d\n", m_nID);
}

void Test(short nID)
{
if(m_nID == nID || nID == kBROADCAST)
printf("ObjA::Test - id: %d\n", m_nID);
}

boost::signals2::connection m_connection;
boost::signals2::connection m_connection2;
boost::signals2::connection m_connection3;

ObjController& m_objCntrl;
short m_nID;
};

typedef boost::shared_ptr spOBJA;

int _tmain(int argc, _TCHAR* argv[])
{
ObjController theObjController;

spOBJA pTheObj1(new ObjA(theObjController, kOBJ1_ID));
spOBJA pTheObj2(new ObjA(theObjController, kOBJ2_ID));

theObjController.CheckCollision(kBROADCAST);

// delete pointer to test that following test msg isn't called since object is gone == slot gone

pTheObj2.reset();

theObjController.RenderObjs(kBROADCAST);
theObjController.TestMsg(kOBJ2_ID); // will be ignored

return 0;

}

I set it up so that I can only signal a specific object if I like, utilizing a specific ID or BROADCAST to all. Yes, I know I can disable slots and turn off individual updates, but since the game will have a relativily small number (20 at most) of objects in a level at a time, I went for the quick and dirty.

The ID approach works but, a better approach would be to have a base message class, and derive messages off of it. Then have the objects when they receive a base message, send back for the actual derived message, but this will work, and I didn't want the over head (although it wouldn't be much more overhead).

The Boost libraries used are signals2, bind, and shared_ptrs. In the engine I add an aggregate to keep a list (vector) of bools on the returns on collision detects, for the game control object to notify the Lua scripts. I don't want any game specific actions in the engine. I also moved the connections into a vector and iterate through them to disconnect on the object reset.

This is just a sample, the code has some typedefs that are in a header file. So, this will not compile or run, but if you would like the complete working source shoot me an email and will send it off.

Well, back to designing the scripting engine component and tying that in.

- .. .-.. .-.. / -. . -..- - / - .. -- . (so you like games? figure out what that Morse code says. :) )

Sunday, June 14, 2009

Signals, Paths, and Static Libraries on the Mac

The last few days I have been thinking about and designing out the engine for the game. As I stated before, all this time I have been writing tests apps and using programmer art and some art the artist of the game prepared to make sure all the mechanics of what I wanted to do worked.

So, now the design is clearer in my mind and ready to get built. One thing I know I wanted in the game is a messaging system. So, instead of writing my own observer/listener and visitor patterns to handle it, I decided I would use, "Boost::Signals." So, I went about putting together a small test to make sure they could work. I include the header "boost/signals.hpp" in my file, set the path to the include and libraries in my project settings and copied in the signals .a library file into my project. I coded up my sample, after fixing some syntax compile errors I built it and all cleared compilation and linking. Next step, fire that baby off. BOOM! Crash!

Okay...what's going on. I step through the debugger and I could see that the code was crashing on the "connect," call of the signal (note: if you are curious and don't know about Boost::signals read up at boost.org, I will not be giving a tutorial on them here). Now, I really have fallen in love with developing on the Mac, but it still has some shortcomings, one of which is XCode. The flaky breakpoints, and sometimes not remembering my changes, I can live with, but the very generic error messages are a real pain. Armed with only sigbus(10) error. I scowered the internet. I found that my problem was a stack overflow. Documents recommended that the Boost:signals library be recompiled on the target machine.

After hours recompiling, re-downloading the library and recompiling and still getting the error. I was at my wits end. So, for grins I said, let me grab the 1.39, latest Boost build. Well, I found in the deliverable notes that "Signals2," had been added to the library and it didn't use a library, just a header file that had everything inlined, which screamed to me, "NO REBUILDING OF THE LIBRARY!" I liked that, scream at me all you want (holla atcha boy).

I think most good programmers, are lazy programmers, so we build tools to do the work for us. My laziness goes even further, I like the tools I'm going to use to already be built for me as well. So, I placed the paths to the new library in my project settings and rebuilt. Sccreechh!

The boost include path couldn't be found. Which leads another pet peeve with the Mac. Since I'm not a unix guy, I wish things like setting environment variables were easier. Noooo! If you read a blog entry of mine long ago, this entry seems like deja vu, because I remembered I had this same problem when installing Boost the first time I wanted to see if it would work in the iPhone environment. I searched back to that blog posting to see how I did all this before.

I found in order to do so I would have to get a terminal window and use the "bash," shell and set the path. So, I followed my earlier blog's instructions and promptly set the boost path, but blew away my other paths. Which rendered "ls," inoperable, leaving me having to type out, "/usr/bin/ls," each time.

So, I turned to a friend, Everett Harris, who is a unix/linux guy (Ohh...I know some unix/linux guys too, is he...no he isn't some pudgy, pasty skinned guy, with long hair, a beard, and wearing suspenders). He instructed me that the easiest way to add/append to the path is (okay, I'm documenting it right here so the next time I forget, I will know how to do it correctly) type the following...

PATH=$PATH=/your path here
export PATH

That's it. So, armed with that knowledge I set my path, and reset all the paths I had blown away. Changed over to "signals2," rebuilt everything, ran it, and viola, my little test now works. Yes, yes, "the journey is, the reward." Sheesh!

So, now back to engine design. I'm laying out all the data, actions, and messages, so I know how I want to hook up all the components, and then I will start coding. Probably, by mid week I will begin coding, at that point I should just be in my zone, knowing what and how I wish to do things...when I am at the point, things tend to go much faster.

Wednesday, June 10, 2009

Dirty Musings

I just verified that when editing your Lua scripts, "Build & Run," will address the changes. The build doesn't have to be "clean," in order for script changes to be noticed. Dirty (changed) scripts, just need to be rebuilt. Still not dynamic as scripting outside of the iPhone's Bundle scheme, but livable.

No coding for a few days, narrowing down my design...designing out my components. I know, I said that about a week ago, but I got involved with the Interface Builder and playing with views to see how I would do my "settings," "high score," etc...views, and doing the music for the game.
So, now back to design...

Design patterns and components is the same approach for my *real* job's (Secure Command...shameless plug) application (Internet Cleanroom...another shameless plug). It has saved me lots of time and headaches, as our small company's product has morphed into other products. We can take the components I designed and plug them in easily, and add new components where need be. Or just add new behaviors (strategy pattern) and change how the app behaves.

So, I will be employing the same techniques here. Which means on this first game, I'm doing lots of work, but hopefully, afterwards I'll be able to crank out another or two faster.

The underlying engines...graphics, physics (limited and basic for this game), file manager, and fonts are done. I still have to do sound and ai. The current ai is crude and was just making sure all the mechanics worked. Now, that I have Lua incorporated I will be scripting most of the ai. I've decided for sound I will be using OpenAL.

The "strategy pattern," and "observer pattern," will be heavily used I can tell you that already. Anyway...there's still 3-4 more hours left for me to get some work done.

Cya, or C++ya, or ObjectiveCya.

Century Milestone

Whooohooo! I just had to do the programmer's cheer, but you know, not too loud. One must stay humble or the Programming Gods will smote you down.

Anyway, its been 100 days of actual work on my game. The journey has been long, but rewarding. I celebrated it yesterday night/this morning (what time is it?) by re-writing my OGL ES graphics engine and I kid you not, after a few compile and link errors, I told myself, "just kick that b*tch off and when it crashes, start debugging." To my amazement, I mean, that usually doesn't happen, it ran flawlessly (staying humble, I will check it out thoroughly later, make sure nothing is lurking to bite).

Also, this evening I finally got around to incorporating Lua into my project. I ran the obligatory "Hello, World!" script to make sure it was working and it is. Whooohooo!!

Now, for those who may still be trying or wanting to incorporate Lua into their projects and haven't been able to get it running or wondering where to start, well I will tell you here, because it wasn't easy for me, and I will try my *best* to make it plain and simple. Ohhh...I hate postings on the web where people leave out the little details.

Anyway, you will (oh yeah...this is strictly getting Lua to run in an xCode/iPhone project) need to grab, "lua-5.1.2(Xcode).zip" (now that I can't remember where I downloaded from since I downloaded it 2 months ago), but if you want it and can't find it, post a comment asking for it and I will email to you. So, the steps...

1) Get lua-5.1.2(Xcode).zip

2) Unzip it

3) It will unzip to the folder lua-5.1.2

4) Open it and double click on the lua.xcodeproj

5) Build the project (just to make sure it builds) ...it will generate a library file but don't try linking with it, too may hassles.

6) Copy the /Src folder from the Lua folder into your project. I created a "Lua," folder inside the "Classes," folder in my project and dumped it there.

7) Find in the /Src folder the files lua.c & luac.c and remove them (they both contain a "main," entry and will screw up the build).

8) Build your project to make sure things can compile (they should).

9) Create a file test.lua and type this in... print("Hello, World!") or whatever you want to print.

10) Copy the test.lua file to your project. I have a folder in my project GameResources, so I added a folder named Scripts and added my test.lua script there. Where ever you copy, just
remember to go to the Xcode menu, select Project and click "Add to Project," and navigate to "test.lua," or if you did create a folder to hold your scripts select the folder, and add it to your project. This will add your script to your Bundle.

11) Now find a file in your project, any one for now, since just testing, I placed my little test inside my view class. Add...

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

Since I wanted the code to just fire off, I added the following lines of code in the view class "initWithCoder" method.

lua_State* L;

L = lua_open();
luaL_openlibs(L);

// The "dofile," needs a path to our script. Well, the iPhone stores your data in the Bundle so
// you will need to grab the path to the bundle.

NSString* bPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"lua"];

// check to see if it was found, if not then you didn't add it to your project properly
if(bPath == nil)
{
NSLog([bPath stringByAppendingString:@"was not found"]);

// abort do something ...some real error handling...whatever
}

lua_dofile(L, [bPath cStringUsingEncoding:1]);

lua_close(L);

That's it..Build and Run...you should see your script write out to the debugger console. Good Luck!

Special thanks goes again to Chris Dillman who pointed me in the direction of including the script in my project, and telling me I needed to get the path to the Bundle. Also, Chris mentioned that each time you touch your script, you will need to clean the build in order for the changes to take place...I haven't actually tried that out to see.

Now...time to get some sleep.

Monday, June 8, 2009

Test Posting

I'm just posting to force a republish of my blog page...ignore.

Sunday, June 7, 2009

Some Right Brain Work

I completed the music for the game, when I figure out how to post it here, I'll put it up. A first snippet of my game. :)

Thursday, June 4, 2009

Easy As Pi

Big man crush for Apple. They make things so very, very simple. Pulled my iMac out of the box (which also is designed well), set it up in 5 minutes. Plugged in my external backup hard drive, and setup my new Mac with my old Mac's work folders, via TimeMachine restore. Viola! That was it...good to go.

Then, spent the next 2.5 hours downloading iPhone 3.0 SDK, and installing that.

Now, I'm up and running on a sanctioned machine..."doesn't it feel good to be doing the right thing, Rod?"

And, so that's what my game really looks like...since on the PowerPC the colors were funky. It is great to see things as they truly are, no more pointing out to my boys, "no, no that's not a green flying saucer, that is a red plate." Haaa haaa...now you think you have an insight into the game I'm making...whatever you are thinking the answer is nope. :) You will have to wait until it is near completion then I will post some screen shots and talk about the specifics.

Okay...my real job beckons.

Wednesday, June 3, 2009

The Arrival

Noooo, noooo...the game isn't finished yet.

I'm just announcing the arrival of my new iMac. So, now I will be legit. I dubbed thee, Hitchcock. My other Mac is Shyamalan.

Alright...back to real day job work, but tonight...I'll be running my fingers across Hitchcock's keys...ooohhh you're so nasty.

Tuesday, June 2, 2009

There Are No Problems, Just Solutions

There is no problem with the way my artist is doing transparency. Thanks to Cara Motycka, Gyuri Grell, and Chris Dillman for looking at the art and pointing me to a tutorial. Turns out my artist had already read the tutorial that Gyuri mentioned, and Cara & Chris looked at the sprites and said they were correct.

So, what's the problem you ask. The answer, and as Dave Chappelle would say, "it pains me to say it people," is either my blending code ("noooooo!" the chorus roars) or the fact that I'm running on a non-sanctioned PowerPC Mac and the color/alpha scheme is funky. RGBA on the PowerPC is GRAB, so things may be working but the hardware is showing me differently.

Also, Chris pointed out to me that my converting the PNGs to PVRTC may also be stripping the alpha out. He told me to just stick with the PNGs. The curious thing is that in the funky GRAB scheme, I found some sprites online that did alpha blend for me. Only the ones with black backgrounds worked though. So, who knows...

When my new Intel based iMac arrives (hopefully this week), I will find out if its me or the machine.

Thanks again to those dear souls that helped me see error of my ways. :)

Gyuri is already receiving a free copy of the game for being the first to answer some previous question I had, and now Chris and Cara will as well. Also, here's a plug for Chris, buy his game "Mouse House, " that is already up in the iTunes store.

Now, back to work.

Monday, June 1, 2009

Doin' The Cha-Cha!

Yesterday a took a step back to clean up some things. Today some steps forward...cha-cha, cha-cha.

I'm proud to announce that I'm now up and running in my own project. I've started laying out my different component classes (yes I am big on Design Patterns). Ahhh...it feels great to be in an organized environment.

I will continue on.

One draw back. My artist is still having trouble creating transparent sprites with Illustrator and Photoshop. I keep getting things that aren't transparent at all, or half of the sprites are transparent.

Call for help...if anyone out there knows how to create transparent PNG images in Illustrator and/or Photoshop please drop me an email.

Thanks!

Now back to work...