Cross-Compilation
Developing your Dreamcast Games with mruby
Summarized using AI

Developing your Dreamcast Games with mruby

by Yuji Yokoo

In this presentation titled 'Developing your Dreamcast Games with mruby', Yuji Yokoo shares insights into programming on the Sega Dreamcast using mruby, a lightweight implementation of Ruby. The session covers various topics pertinent to both newcomers and experienced developers interested in retro console programming.

Key points discussed in the video include:

  • Introduction of Presenter: Yuji Yokoo, a software developer from Adelaide, originally from Tokyo, introduces his background and interests in console video games.

  • Overview of Dreamcast: He explains what the Dreamcast is, its specifications, history, and why he chooses to develop for this 20-year-old console despite its age. He describes the Dreamcast as a beloved console within the indie development community despite the challenges of dwindling hardware availability and peripheral costs.

  • Importance of mruby: Yuji discusses mruby as a lightweight Ruby implementation suitable for embedding into applications. He highlights its features compared to CRuby and its seamless integration with C, which is essential for Dreamcast programming that typically involves C.

  • Development Environment: He introduces KallistiOS (KOS), a development system for the Dreamcast that includes various necessary tools like compilers and libraries for writing games.

  • Development Process: The process of cross-compilation for the Dreamcast is outlined, showing how code is compiled for the SH4 architecture of the Dreamcast. Yuji emphasizes the importance of creating bootable images for disc use.

  • Syntax and Code Examples: Yuji provides code snippets demonstrating how to integrate mruby with C code, particularly focusing on reading button states from the controller and how Ruby functions can elegantly interface with C.

  • Challenges of Hardware Connection: He explains the various methods for getting programs onto the Dreamcast, including homemade serial cables, highlighting the difficulties related to connectivity and hardware limitations.

  • Conclusion: The presentation wraps up with gratitude expressed towards the Ruby community and encouragement for interested developers to join existing communities. A quick demo of a puzzle game follows, showcasing his application of the concepts presented in the talk.

The main takeaway from Yuji's presentation is the exciting potential for modern development on retro consoles using tools like mruby, unlocking creativity and community engagement in the realm of indie game development for legacy systems like the Dreamcast.

00:00:00.000 Never speak to anyone who isn't me. His name is Yuji Yokoo. He grew up in Tokyo but now lives in Adelaide.
00:00:07.049 To continue the thread of his martial arts expertise, Yuji has a black belt in Judo and Brazilian Jiu-Jitsu, so watch out! He also brews beer and makes cider and other alcoholic beverages. Yuji would love to utilize IoT technology to monitor how the fermentation process is going.
00:00:22.170 He loves console games and his talk will demonstrate how he created a mruby environment for Dreamcast games.
00:00:28.380 Please welcome Yuji.
00:01:08.090 Thank you! So, to start with, this session is going to be about the Dreamcast and mruby. You might be wondering why someone would talk about a 20-year-old video game console and how to program for it. But that’s because this is a single track conference, so you have no other choice! I appreciate you deciding to stay here. I'm sure people have other commitments and you might be tired after traveling this morning, so thanks for being here.
00:01:55.759 What you see on screen is coming from my Dreamcast console. This is running on my Dreamcast video game console, and I have a controller that I can use to navigate through the presentation. While I said this talk would be about developing your Dreamcast games with mruby, I've also spent a lot of time developing the presentation tool. So, it's really about developing Dreamcast games and the presentation tools using mruby.
00:02:22.820 Before diving into the technical content, let me introduce myself. My name is Yuji, and I'm a web developer working for a company called My Times in Adelaide. I primarily work with Elixir, F#, and Elm.
00:02:30.140 Currently, I’m not using much Ruby at work, but I still love the language. I transitioned to using mruby with C because you often have to write some C code for it. I wasn't a complete novice with C, but I wasn't an expert either. I am originally from Tokyo, Japan, but I now live in Adelaide, South Australia. For any international visitors who may not know, Adelaide is about 700 kilometers from Melbourne. Yesterday, I traveled this distance, and it’s quite a long way.
00:03:23.700 Last year, I presented at RubyConf Taiwan, where I traveled even farther, from Melbourne to Hong Kong to Taipei, so this is quite an improvement! Thank you for being so close, Melbourne.
00:04:02.790 Now, let's quickly go over the table of contents. First, I will provide an overview of the application I developed. Then, I'll explain what the Dreamcast is since I realize some people here might not know about it at all. Afterwards, I will discuss what Ruby is and introduce you to KallistiOS, which is vital in Dreamcast software development. I will outline the development steps and present some code from my application. Finally, I'll explain how to run it on a Dreamcast and, if I have time, I would like to do a demo. However, I realized earlier today that while I tested the presentation, I haven’t tested the demo game. If the demo doesn't work, you'll just have to use your imagination.
00:04:40.169 The application currently running is the presentation app I developed using mruby for the Dreamcast console, which I have named 'Dream Present.' This app runs on the Dreamcast and right now is a live demo, so I’m a bit nervous, realizing that anything could go wrong at any moment. I’d like to keep it that way.
00:05:07.820 Recently, I developed some features including syntax highlighting for code, though the highlighting isn't very smart and doesn’t cover the entire Ruby language. It does cover some names in text highlighting, and it can show PNG images. At the bottom of the screen, there’s a time progress bar, along with the red Ruby logo indicating the time progress and the blue swirl of the Dreamcast indicating the page progress.
00:05:55.599 Additionally, the application can draw horizontal and vertical lines and move back and forth between pages. However, I would like to mention that there isn't much safety checking, so if it shows a summary page or even crashes, that’s also considered a feature.
00:06:25.270 Here’s an example slide showing some of these features. The white text might be hard to read against a dark background because the background image is quite dark. It can display colored text and lines, with a PNG image in the top right corner. Of particular note is the code section featuring syntax highlighting.
00:06:59.650 Initially, I started with the static Mitchell string as hard-coded presentation data in my application code. However, this quickly became too complex to manage, leading me to create a separate file. I began adding ad-hoc features.
00:07:21.219 This resulted in a rather difficult-to-use presentation description language. I intend to improve it at some point, but for now, this is what the source for the previous page looks like.
00:07:33.310 Now, what is the Dreamcast? The Dreamcast is a video game console, and there are currently two units here: one that is operational and another spare unit in case the first fails. When I started working on this, I referred to the Dreamcast as Sega's current video game console because it was released in 1998; however, they discontinued its production in 2001. Some suggested I call it Sega’s latest console, but then they released the Mega Drive Mini, which made the Dreamcast no longer the newest console. Therefore, I’ve settled on calling it the best video game console.
00:08:40.450 The Dreamcast unit was released in 1998 and runs on a SH4 processor at 200 MHz, featuring 16 MB of RAM. When you compare this to a typical notebook developer's equipment, which might have around 16 GB of RAM and a 2 GHz or faster CPU, you can see this is a very limited environment compared to the modern development setup.
00:09:07.340 So why Dreamcast? Personally, I really like the Dreamcast, and 2018 marked the 20th anniversary of its release. I wanted to create something special for that anniversary. I started working on it in 2018, but nothing was working out by the end of that year.
00:09:34.460 It took a lot longer than I originally anticipated, but now I have managed to get something working. I also still have a working Dreamcast console. I purchased it as my second unit after the first one broke down in 2002.
00:10:01.570 The second unit is still functioning, touch wood, but aside from my personal reasons for loving the console, it still has a strong community of indie and homebrew developers. Many are continuing to create new games for the Dreamcast, and it has a good set of open-source tools for development that are fairly easy to access.
00:10:49.199 However, there are several disadvantages. The most significant is that no more units are being produced. Since they are about 20 years old, many are experiencing wear and tear, with their optical disc drives failing frequently. As the consoles break down and no longer produce, we are gradually running out of functional Dreamcasts.
00:11:06.629 Another drawback is that peripherals can be difficult or expensive to acquire; if you want a network adapter, for instance, they are very costly. Additionally, there is no App Store or internet-based distribution for games, meaning if you create a game you want to sell, you have to distribute it physically on a disc or provide users with a disk image for them to write onto a CD.
00:11:45.479 This limitation could be seen as a positive as well, since you cannot be removed from an app store!
00:12:04.950 Here's a quick comparison between the Dreamcast and the PlayStation 4. As you can see, there is a massive difference in speed, RAM, and pretty much everything else.
00:12:26.640 Now, let’s talk about mruby. Most people here at RubyConf Australia have probably heard of mruby, but I suspect that many do not have any experience with it. It's a lightweight Ruby implementation, which means there are multiple implementations of Ruby. The most well-known is CRuby, or MRI, but others exist as well.
00:12:41.599 mruby implements most of the 1.9 syntax and some standard features, while aiming to also support many features of ISO Ruby. Although it’s mainly based on 1.9 syntax, a lot of features from later versions, like 2.7, have been ported to mruby. Its intended purpose is for embedding so, what you can do is compile mruby into C code and integrate mruby functions into your C program.
00:13:32.040 In the context of embedding Ruby, you might think about the native extensions in Ruby, which allow you to call C functions from Ruby. However, with mruby, you also have the option to write Ruby functions that can be called directly from your C program. This makes integration much more seamless. Also, since I’m mentioning compilation, you might wonder if it's faster than CRuby. In reality, it can be a bit mixed; some processes are faster, but CRuby, especially version 2.7, has become quite fast.
00:14:31.660 mruby was first released in 2012, mainly for embedded environments. If you want to deploy it on a very small or limited device, it might not support processes or threads, or even have a file system or network I/O. These functionalities are typically found in CRuby but can be made optional in mruby.
00:15:51.349 Advantages of using mruby include writing logic in Ruby, which can make me feel more productive compared to using C. Furthermore, it integrates easily with C, which is vital in development for the Dreamcast. Generally, Dreamcast programming is done in C but can be simply integrated using mruby.
00:16:55.169 Before moving on to the overview of how we develop Dreamcast software, I would like to introduce KallistiOS, also known as KOS. It is a FreeBSD-licensed development system that includes libraries, compilers, linkers, and pretty much all the tools you need to write Dreamcast games.
00:17:51.299 For writing a game or application in C for the Dreamcast, you would start with your C code and then cross-compile it. If you aren't aware of cross-compilation, it involves producing a binary intended for a different architecture. For instance, you have an Intel processor on your machine and you want to compile something for the SH4 processor of the Dreamcast. So, you compile it on your Intel machine to get the SH4 binary.
00:18:39.630 Next, you use KOS's libraries to link it against the Dreamcast libraries to create an executable file. Typically, you'll need to create a bootable image, which allows you to write it onto a disc for the Dreamcast. Interestingly, even though I mentioned that you don't need to modify the hardware to run your code, there’s still some protection against piracy. When you put a CD in the Dreamcast, it tries to read the binary in a scattered manner from specific locations, and in order to create a bootable disc, you need to scramble the binary in the format that the Dreamcast expects.
00:19:44.300 When integrating mruby, you would compile your mruby and C code, producing bytecode—this is compiled binary code for the virtual machine. This bytecode runs on a virtual machine and is cross-platform, as long as the same virtual machine is present. After you produce the bytecode and C code, you link them with KOS and the mruby library, which includes the Virtual Machine (VM), generating the executable.
00:20:53.220 I'll briefly show you how my application initializes and runs in C. In the main function, this simplified version declares a Ruby bytecode that’s defined elsewhere. It performs video initialization for the Dreamcast, initializes mruby, builds the modules and functions for mruby, and then runs the MOV code.
00:21:30.470 If you are not following the details, basically, the C main function initializes and starts the movie. Now, let me quickly show you what the bytecode looks like—this is just a sample structure of instructions, and it’s not very readable since it’s just hex numbers.
00:22:25.090 Next, I would like to demonstrate how to integrate C and mruby to read the controller's start button state. Each button has a specific mask, and for the start button, the mask is defined as 1 shifted left three times.
00:23:04.400 Bitwise operations are used here, similar to logical operations, and they enable us to check if a specific button is pressed. If it is pressed, you perform a bitwise AND operation to determine if the state of that specific button is on. In this case, the start button has been pressed, as indicated by a nonzero result.
00:23:39.240 I would now like to show you the definition of a function called `button_start?` that unpacks Ruby arguments when you call a C function from mruby. This is how you check if the start button is pressed in a more readable way. The function unwraps the Ruby arguments when calling C functions so that the code sees them as Ruby boolean values.
00:24:40.880 In this case, the application code checks if the start button is on. When you're writing application code, it’s the plain Ruby code that does this without needing to deal with the underlying complexity.
00:25:44.159 Once you’ve written the code, you need to build the binary to run it on the console. However, first, you need a way to run it on the Dreamcast. Emulators are incredibly handy as they let you run your program on your PC without needing the actual console.
00:26:27.780 That said, performance may vary and the emulator may not fully replicate the original hardware. I have an example screenshot where the presentation is running in an emulator along with a terminal window providing debug output, which is otherwise not accessible on a Dreamcast without a connected serial cable.
00:27:33.290 Connecting to the Dreamcast is limited. Back in 1998, USB technology was just becoming popular, so there’s none on the Dreamcast. However, you can use the serial port, which adds some limitations as well.
00:28:30.080 There are several ways to get your program onto the Dreamcast, such as using SD card readers, broadband adapters, or serial cables. Each comes with its own challenges. For instance, while SD card readers are more cost-effective than CD-Rs, they still require manually switching out cards. Broadband adapters are handy but expensive; I found one listed on eBay for about $200 in Australia.
00:29:21.880 Eventually, I decided to create my own serial cable, although I’m not particularly skilled in electronics. The instructions I found online recommended using an existing link cable, but I did not want to pay hefty prices for the original cables. Instead, I opted for a more affordable component—which I successfully cobbled together, albeit rather poorly. This handmade cable works but with some reliability issues.
00:30:31.570 Despite its imperfections, I've managed to create a functional serial cable for the Dreamcast. To summarize, I’ve covered developing Dreamcast games, booting your code on the console, and the journey I took to get there. I skipped over many details, but now you're aware of the fundamental processes.
00:31:24.960 For my current project, I've transitioned to using Docker, which takes only 2.4 gigabytes of disk space instead of the previous two to three hours of setup with Vagrant and VirtualBox. I plan to work on a user-oriented guide and expand the features further. Currently, my user base comprises just myself, so if anyone else in the community joins me in exploring mruby on Dreamcast, that would be a welcome addition!
00:32:34.260 I want to extend my gratitude to all the Ruby developers out there, especially those from the community who have provided invaluable tools and resources. I owe thanks to Dreamcast enthusiasts, especially the welcoming and encouraging members of the Simulant Discord community. If you're interested in Dreamcast development, I encourage you to reach out and join these communities.
00:33:38.070 Lastly, thanks to RubyConf Australia for allowing me to present and for the encouragement from my peers like Adam, Olly, and Paul, who assisted me in refining my content. Without their help, it would have been a far worse version of this presentation.
00:34:48.050 If you're interested, here’s a list of links, and please reach out to me on Twitter with any questions related to this topic. I am open to discussing anything related to mruby and Dreamcast development.
00:35:12.850 Now, let me attempt a demo of my puzzle game. If I can switch over the console and swap out the discs, let's see if it works.
00:35:46.820 The logo during the boot sequence is mandatory, but I did add a message stating 'Not Licensed by Sega.' This demo game is reminiscent of a well-known clock puzzle game. Now, it's quite difficult to play from this angle, but let me see. I'll just clear one line and wrap things up.
00:36:21.199 Thank you very much for your attention!
Explore all talks recorded at RubyConf AU 2020
+15