Category Archives: Greebles

First Cross-Platform Experience!

This week, for the first time, I attempted to build the Greebles project on Mac OS X. I’m happy to say that I didn’t have too many surprises. Here’s what I learned:

On OS X, every piece of software that runs as anything more than a console program, must be bundled as an OS X App. Thankfully, CMake makes this really easy! Here’s all it takes to tell CMake to generate an OS X App for the Setup Dialog:

set(MACOSX_BUNDLE_NAME setup)

add_executable(setup MACOSX_BUNDLE ${SETUP_SRCS})

target_link_libraries(setup ${SETUP_LIBS})

set_target_properties(setup PROPERTIES MACOSX_BUNDLE TRUE)

# REST OF CMAKE

And with that CMake will compile your executable, and place it in an OS X App that you may then launch as you would any other.

The other thing I learned, was that OS X Apps are not meant to receive arguments on the command line. Oops. I had built a couple of the dialogs to rely on those. Time to refactor. 🙂

Status Update

Remember a while back when I said there were only three parts of the project? Turns out there’s a few more than that. 🙂 Not only is there a form for Setup and Custom Game Settings, but also for clearing the high score list, (Zap) joining a network game, and displaying errors.

I’ve spent the past couple of weekends working on those, but they’re pretty much done now! Here’s a screenshot of each of them:

Setup:

Setup_016

Custom Game Settings:

Custom Game Settings_017

Join Network Game:

Join Network Game?_019

Zap High Scores:

Are you sure?_020

Error Dialog:

Error!_018

For the most part, they’re pretty simple, it just took some time. But now they’re all done, and they have everything in place to interface with the game itself, which is actually what I’ve been looking at next.

I’ve started working on designing the game itself this week. I’m mostly just throwing ideas around and seeing if they would work/fit with all the different needs, but it’s still really fun! Especially when I think about how the AI is going to work, but that’s still a ways down the road. Right now I’m thinking more about the game state machine, and how I’m going to build the menu system. Hopefully in the next month or so, (school permitting) I’ll have the menus in place and wired up to some of the dialogs I created up above. Huzzah!

wxWidgets and proper user of Connect()

I recently fixed a painfully subtle bug, and decided to share my experience for all those who follow hereafter. In the main wxFrame class of the setup program for Greebles, I have several data members that stored the information represented on the GUI. Whenever a form component changes, it calls an event handler that updates the internal data member.

When I started working on adding support to be able to do some drag and drop stuff, I added a new event handler; but when this event handler tries to access the relevant data members, suddenly everything was trashed! Pointers were either null or pointed to garbage, and the program would segfault. I had no idea why. The only thing I had seen before that may have matched the symptoms was heap corruption. And I really didn’t want to believe that it was heap corruption. I was double-checking all my pointers, I couldn’t see any way for that to happen.

Well, I finally explained my problem on the wxWidgets forums, and got an answer right off the bat. It turns out that the wxWidgets connect method, which is used to connect component events to event handlers, needs to know the context of the call. It needs to know the class that owns the event handler, also known as the event sink. If you don’t give it one, it just uses the this pointer.

Typically, that works fine because you’re Connect()ing events in the class that owns the event handler. But I was Connect()ing handlers to member components. Because of that, Connect() thought that the member component was the one who owned the event handler, when really it was the parent component. As soon as I specified the correct event sink, the problem disappeared. Check out my forum post for the code examples.

Sometimes, Magic.

I decided a while back that I was going to use GLFW for Greebles. It’s lightweight, cross-platform, meets the needs, all that jazz. But, doggone it, they just had a major release, so I figured I’d better get up to speed with the changes. As a study in preparation for Greebles, I decided to port a game I’d written using GLFW 2.8 in Windows, to Linux, and update it to use GLFW 3.0. So that’s what I’ve been working on lately, and it’s just about done. Just minor fixes left. (Hopefully) As a sidenote, you can check it out on github.

Here’s the exciting part. After updating the code to use GLFW 3.0, I got this weird bug. The camera wouldn’t follow Calvin around. I started printing out some debug data to see what was happening. The camera would correctly adjust it’s position, but when execution came back around, it was right back where it started. Da heck?

I decided I’d better brush up on my GDB skills and see what’s really going on, but when I fired up GDB, it told me it couldn’t locate any debugging symbols. Oh yeah, I was compiling for Release, better switch that to Debug. Fire it up aaand….

The bug is gone. Da heck??

It hit me that I had a big problem. Bugs like this have been nightmares for me. Typically, you write some piece of code that isn’t really standard, so when you compile your code for Release and the compiler attempts to optimize it, you get crazy stuff happening!

So I started doing research, trying to figure out where it could be coming from. I found this. Apparently, complete support for C++11 doesn’t arrive until GCC 4.8. I check my version, I have 4.7. Ahhhh, this could be something. Found this next. I installed GCC 4.8 and rebuilt everything and tried again in both Debug and Release. And you know what?

The bug is gone. Da heck? 🙂

Keep Moving Forward

I’ve been working diligently on Greebles for most of the weekend, I’m happy with the progress I’ve made. Development seems so easy in Sublime with CMake under Ubuntu.

So, quick overview of the whole Greebles project. There are three separate “Programs” I’m writing: 1) The game itself, 2) A “Setup” program, 3) A “Custom Settings” program. The second two are just GUI forms for configuring the game settings. I’m going to finish two and three before one, and two before three.

So I should have ordered them like this:

  1. Setup Program
  2. Custom Settings Program
  3. Game

I’ve been cruisin’ on Setup this weekend. I decided to store all game data in a sqlite database that all three programs could share, so I finished designing the Setup part of the database, and have been coding up the Setup GUI. Here’s a quick preview:

setup-screenshot

I’m using wxWidgets for the form GUIs, plus wxFormBuilder to help design them and generate some of the code. Right now only the sound/music/difficulty settings actually get saved, I’m hoping to finish up the rest in the next week or two.

One of the challenges I faced this week had to do with the checkboxes next to each players name, signifying whether or not that player is going to play. In wxWidgets, checkboxes have to have a label next to them. If you specify an empty string “” for the label, no text shows up, but clicking the checkbox still highlights this empty area next to it…kind of ugly. Thankfully, someone whipped up a wxWidget Checkbox component that doesn’t use a label, problem solved!

Progress!

This week I finally successfully launched the original Greebles running on an old eMac that I found! Now I’ll be able to compare to the original as I develop the modernized version.

    

Turns out that good documentation is kind of hard to find when it comes to getting classic mode running on OS X 10.4, after lots of searching I finally found this page that lays it out extremely well. Hopefully it’s of use to someone else at some point. 🙂

Next it’s back to framework development for the game. Stay tuned. 🙂

Greebles!

Once upon time, in the far away land of Burkholder, there was a young classroom of curious computer literacy students. They were subjected to grueling blindfolded typing tests and mind-numbing lectures each morning, but twas not all awful. On occasion these friends found time to amuse themselves by engaging in virtual contests of dexterity and skill, which cast rays of joy into their youthful souls. The most popular and exciting of all these contests was Greebles. Seemingly without limits with regard to the number of contestants or length of play, Greebles was adored by all.

Sadly, their joy could not last.

For Greebles had been made for the PowerPC architecture of Mac OS 9, built by the mighty kingdom of Apple. Soon thereafter however, Apple abandoned OS 9 and the old architecture. The serfs of Stairways software, the publishers of Greebles, would also abandon their product, leaving thousands of loyal followers without means to preserve the joys of their youth.

Many years passed, and people began to forget about Greebles. One of the youths from Burkholder however, began to remember. He was an apprentice in the ways of software development, and desired to undertake a quest to use his skills to resurrect Greebles. He sent word to Peter Lewis, the leader of Stairways software, explaining his intentions. Many days passed before word came back, but when it arrived, the youth was overjoyed to read that Peter gave his blessing to the quest, and included with his message ‘sprites’, ‘level definition files’, and ‘sound effects’ to help the youth.

The young man embarked, anxious to complete the quest and restore joy to his friends of ages past. Sadly, he underestimated the skill, strength, and time that the quest would exact of him. Twice he began, and twice he failed. For a time, he gave up, painfully aware that he lacked what was necessary to achieve his desire. He continued his apprenticeship, and began university studies, absorbing and learning all he could of the ways of the master developers. However, always, in the back of his mind, was Greebles.

Now, nearly half a decade later, he is ready to try again.

http://www.stairways.com/action/linkthru?greebles

http://www.infam.ch/greebles/

http://www.youtube.com/watch?v=tMnthmrB-eo