Tuesday, 6 June 2017

Gotchas When Porting C++ and OpenGL Applications to the Dreamcast

Over the past month or so I've been steadily working on porting my game engine Simulant to the Dreamcast. While it's not quite ready for prime-time, I did discover a lot of road-bumps along the way, and I thought I should write some of them down so that anyone else porting to the Dreamcast will at least have some results on Google to look at!

Compile the Dreamcast SDK with GCC 4.x

It didn't take very long to compile my code, but when it came to linking all kinds of trouble awaited me. Whenever I tried to link, most of the C++ symbols (things like string and vector) were missing. After several days trying different linker flags I decided the problem must be with the SDK itself. A quick `nm` of libstdc++.a showed up the problem; only a handful of symbols were in there!

I've been using a Docker container to compile my code, which is fortunate because it allowed me to gradually roll back the Fedora version until I hit one that correctly compiled libstdc++. Fedora 21 is where it worked!

The moral of the story is that for some reason, GCC 5.x and above will not correctly compile libstdc++.a from GCC 4.x - so if you're compiling the SDK for C++ code, you're going to need to use an old GCC version.

Don't rely on std::atomic or std::async

The SH4 CPU only has a single limited atomic instruction which rules out support for std::atomic. That by itself wouldn't be so bad, but it turns out that even though the standard defines that std::async can be implemented without atomics, GCC hasn't done that.

In most cases it's trivial enough to build what you need using std::mutex and std::thread - but it is a bit of a hassle.

std::chrono::high_resolution_clock ... er... isn't

This had me confused for a while. I had a sample GL application running; a spinning cube, and it would run at a consistent 1FPS. I know the DC is slow compared to modern machines, but, 1FPS for a cube?!

Turns out that the "high resolution" timer had an accuracy of 1 second! Using the built-in KallistiOS timer functions fixed it.

libGL is still a WIP

The GL port for the DC is a great little library, but it has some rough edges. I recommend that you get your application runnable on both your PC and the DC and focus on targetting GL 1.1. If the graphics in your application don't work on the Dreamcast but do on the PC then investigate and submit a patch!

Saturday, 10 December 2016

DreamPi 1.6 Released!

'This'is really just a bug fix release, although it's a pretty good one!
  • Incorporated a program called dcgamespy which was written by Jonas Karlsson which manipulates packets of games like Starlancer to avoid your ISP blocking them as a security measure. Thanks again Jonas!
  • Reduced the modem communication rate which should hopefully fix a lot of those weird "DreamPi doesn't work for me?!" issues, and may restore support for serial modems. Maybe.
  • The script now waits for an Internet connection before doing anything, this should fix the issue where the AFO routing rules wouldn't take effect.
 Download the new image here.

Sunday, 6 November 2016

DreamPi 1.5 Released!

This is a big release with new features and multiple bugs fixed:

  • New software is included written by Jonas Karlsson called "dcvoip" this system process makes the VOIP communication in Planet Ring work! The software is distributed with permission.
  • There is now built-in support for the upcoming Alien Front Online servers that will allow your vanilla normal AFO CD to work without a boot disc! (Thanks again for Jonas for the information to do this).
  • The Pi's firmware has been updated which should bring better device support
  • A bug has been fixed where the DreamPi software wouldn't shut down correctly
  • The modem command timeout has been increased which fixes a number of bugs on modems which are slow to respond (for some reason...). Thanks to Neoblast on the DC-talk forums for finding this.
  • Fixed a bug where the DreamPi process would boot before there was an internet connection (mainly affected WiFi) and would require restarting multiple times to get things to initialize correctly.

Special thanks to PCwzrd13 for being an awesome tester!

You can download the new release here. If you have any problems please post on DC-talk or create an issue on GitHub.

Saturday, 10 September 2016

SEGA Should Resurrect the Dreamcast Brand

Yesterday, it was the 17th anniversary of the SEGA Dreamcast in the U.S. and the occasion caused Twitter and Faceback to fill with birthday greetings for the console that refuses to die. If you're reading this you are probably well aware of the stubborn and ever-growing “Dreamcast Scene”, but if this is news to you then I'll give you a quick overview.

After SEGA stopped supporting their last home console, homebrew developers made tools to create games for it, and every year more and more games created by indie developers are released. On top of that, the Dreamcast continues to gain more and more online multiplayer games as aspiring geniuses reverse engineer the old game servers. Just in the past year alone, Chu Chu Rocket, Toy Racer (dial up), PAL Quake 3 and The Next Tetris, have returned from the dead. On the horizon is Alien Front Online, and there are sure to be more to come. There are weekly game nights scheduled for both the U.S. and UK, and well over 100 people now regularly play online. Which is quite some achievement considering you have to actually do some soldering to get the dial-up Dreamcast to connect in a fibre-optic world.

In summary, the Dreamcast isn't dead, it's alive and well. Sure it doesn't compete with current gen consoles but no other console in history has had as much community support. Which brings me onto the main topic of the article; SEGA should bring the Dreamcast back.

Saturday, 14 May 2016

DreamPi 1.4 Released

This is a bug fix release.

  • New image. Fixes corruption issues with the previous release.
  • Improved Pi 3 support. This release is tested to work with the Pi 3.
  • Updated firmware. Includes the latest Raspbian updates (Linux kernel 4.4)
  • Improved IP allocation. This code has been completely rewritten to use the arping command and seems much more reliable and fixes several known issues.
You can download the release here.

Friday, 22 April 2016

Avoid C++ Typo-bugs with this One Cool Trick!

Recently I found an online quiz created by a company which develops some static code analysis tool. You were presented with buggy C++ code which the tool had detected and you had to click on where the bug in the code was.

The large majority of the bugs in the questions were down to typos. These normally occurred when someone had written the same line of code 3 or 4 times, but with different attributes (e.g. .x, .y and .z for a vec3)

Well, here's a neat trick that will allow you to avoid such typos. In the following example I recalculate the min/max values of a bounding box given a vector (pos):

            /* Iterate the X, Y and Z attributes and assign them if necessary */
            auto attrs = { &Vec3::x, &Vec3::y, &Vec3::z };

            for(auto& attr: attrs) {
                if(pos.*attr < bounding_box.min.*attr) bounding_box.min.*attr = pos.*attr;
                if(pos.*attr > bounding_box.max.*attr) bounding_box.max.*attr = pos.*attr;

By using C++11 initializer lists, and auto, you can elegantly create a list of pointers to member attributes. C++11 range-for loops allow you to iterate them easily without a bunch of type definitions, and then you can just apply the pointers to the two vectors. This ensures that you never accidentally check the value of .y against .x or something like that. It's also fewer lines of code than repeating the if checks (4 vs 6). You could also tidy it up more if you create some extra reference variables in the loop. Win.

Saturday, 16 April 2016

DreamPi 1.3 Released!

This is a minor release which simply updates the Raspberry Pi firmware on the image. This should mean that the Pi 3 is supported, but I don't have one to test that!

You can download the new release here!