RubyConf Taiwan 2023

Developing cross-platform mruby software for Dreamcast and Wii

#rubyconftw 2023

Developing cross-platform mruby software for Dreamcast and Wii

With mruby, we can write Ruby for many environments including old video game consoles. I am working on a cross-platform library for mruby so software written for mruby on Dreamcast can be run on Wii with little change to the source. I have ported the block puzzle I showed at RubyConfTW 2019 to Wii, and am now working on the presentation tool.

I will tell you about what is involved in making a cross-platform mruby library for Dreamcast and Wii, as well as challenges and lessons learned.

This presentation will (hopefully) be delivered on either of those consoles and will include some live demos.

RubyConf Taiwan 2023

00:00:28.960 Hello everyone! That was me trying to say hi.
00:00:39.559 I'm back and I'm so happy to be here. I was here four years ago for RubyConf Taiwan and I presented on running mruby on Dreamcast back then.
00:00:46.680 This time, I'm back with my Dreamcast. I don't want to lift it too high because it's all connected, but I brought my spare Dreamcast and my Nintendo Wii.
00:00:52.440 I'm really excited to share my work on developing cross-platform mruby software for Dreamcast and Wii. First of all, I'd like to apologize.
00:01:01.120 I had hoped to run the entire presentation from my Wii, but I encountered several critical bugs that I couldn't resolve.
00:01:07.840 I tried to fix them up until earlier this week, and I decided it would be better to present from my MacBook instead.
00:01:12.960 While this means the presentation is being shown from my MacBook instead of the console, it's also a lot nicer to read as the screen output is more eye-friendly. I'll still show you what I've got running on the Wii at the end of this presentation.
00:01:30.960 I believe that sometimes we need to be ambitious. If we never fail, we're probably not trying hard enough. Although I didn't quite achieve what I wanted, I hope you'll still find this presentation enjoyable and interesting.
00:01:42.360 Here's a table of contents for my presentation: I will talk a little about myself, discuss Dreamcast and Wii, explain mruby, cover the motivations behind my work, discuss the similarities and differences between Dreamcast and Wii, and share insights about the development process.
00:01:56.400 I'll also address the challenges I faced and the changes that were required in both C and Ruby code. Finally, I hope to demonstrate my working software and conclude with a summary and useful links.
00:02:10.399 About myself: I'm Yuji Yokoo from Tokyo, Japan. I grew up in Tokyo and have been living in Adelaide for about a decade. However, last weekend I started moving back to Tokyo.
00:02:18.040 I have packed up my townhouse in Adelaide, but I still don't have a permanent address in Tokyo. I currently work for Cipher Stash, a startup in Sydney that focuses on database encryption technology.
00:02:29.519 If you're interested in encryption technology that enables data lookup, please come and speak with me. I mention this as they are my speaker sponsor, even though today's topic is unrelated to their work.
00:02:39.320 Now, let's talk a bit about the Sega Dreamcast. I have a fondness for the Dreamcast for many reasons; I believe it's one of the best video game consoles ever made.
00:02:50.080 Released in 1998, it features a Hitachi SH4 processor running at 200 MHz with 60 MB of RAM and a GD-ROM drive that allows for about one gigabyte of data storage.
00:03:01.120 Except for the later revision consoles, all Dreamcast units can run custom code by just writing a specially formatted CD, meaning no exploits are needed.
00:03:10.399 This feature has facilitated the continued release of indie games, and I recently purchased a game disc called Driving Strikers, which was released this year for Dreamcast.
00:03:19.680 Now, let's move on to the Nintendo Wii. Released in 2006, it was not particularly powerful compared to other consoles of its generation, but Nintendo chose not to compete in processing power and graphics.
00:03:27.599 The Wii features a 729 MHz processor and significantly more RAM than the Dreamcast, indicating a considerable difference in capability.
00:03:38.879 Interestingly, it comes with an SD card slot, but by default, it does not allow non-official software to run unless properly released.
00:03:48.000 However, there are several easy exploits available.
00:03:50.880 For example, I previously used an exploit on the Wii called Smash Stack, which uses vulnerabilities from the Super Smash Brothers Brawl disc.
00:04:01.120 More recently, I employed another exploit called Letter Bomb that involves using a specially crafted message file saved on the SD card and opened in the Wii’s message board.
00:04:10.600 As a result, exploiting the Wii is relatively easy, but no one can produce a self-booting disc for it unless they are a proper manufacturer.
00:04:20.520 Now, let's briefly talk about mruby. Many of you are likely familiar with mruby as it's a lightweight implementation of Ruby.
00:04:28.720 If you're not sure which implementation you're using, you're likely using CRuby, so know that alternatives like JRuby and mruby exist.
00:04:39.159 Mruby is designed for embedded systems and integrates well with C programs.
00:04:45.760 Since 2012, mruby has supported Dreamcast out of the box, including a build configuration file for Dreamcast.
00:04:54.640 And just this October, it also received a build configuration file for the Nintendo Wii, allowing for library development with only one command, provided you have the necessary platform software installed.
00:05:06.759 Now let’s discuss the motivation behind why I pursued cross-platform development between Dreamcast and Wii. The Wii was an incredibly popular console, selling over 100 million units worldwide, which is impressive.
00:05:21.480 Given that the Wii is a more recent console, many units likely remain unused, providing an opportunity to reach those potential users.
00:05:34.120 If I can develop software that works for both the Wii and the Dreamcast, I can significantly increase the number of developers working on Dreamcast projects.
00:05:41.799 The ease of exploitation is a significant factor, but perhaps the most compelling reason is that I have a Dreamcast at home.
00:05:57.120 As I mentioned earlier, there are many differences between Network architectures, but there are also similarities.
00:06:06.600 Both platforms have free open source SDKs and use GCC, which makes them good targets for cross-platform development.
00:06:12.400 Kalisto is the development environment for Dreamcast, also known as Chaos, and it provides access to file system control, I/O graphics, and other features.
00:06:23.839 Devkit PPC is geared towards PPC, providing GCC and linking tools, while libogc is a low-level library for Wii and GameCube.
00:06:33.320 Even though libogc is not very feature-rich, many libraries are built on top of it. Devkit PPC and libogc are designed to be used together.
00:06:40.199 In commercial software development using libogc and devkit PPC, you may need to carefully check the licenses as they differ.
00:06:47.559 Now let's look briefly at the development process. To get started, you need to write some C code, which performs platform-specific initializations.
00:07:00.440 This C code will set up mruby, define classes, attach functions, and load your program.
00:07:08.479 Once the loader is complete, you can write the actual Ruby code. You'll define your top-level Ruby file that utilizes the modules specified in the C code.
00:07:24.080 As you develop your Ruby application, you may find the need to write additional C code to access hardware features such as video RAM or controller states.
00:07:35.080 For instance, you will need to wait for a vertical sync (vsync) signal to keep the game running at a constant rate.
00:07:45.760 This C function typically returns a value that can be used in the mruby environment to maintain consistent timing in your game.
00:07:57.559 After writing your Ruby code, you will compile it and produce bytecode, which is a representation of your program in numerical format.
00:08:05.559 You don't have to understand the bytecode itself, but it's important to know that this bytecode is combined with the C code to produce object files.
00:08:14.399 These object files need to be linked against the platform's libraries and the mruby VM library to create the executable formatted for the console.
00:08:24.279 In most cases, even though the output is an executable, you'll need to perform an additional step to build an image required for the game console.
00:08:34.519 The tools provided with the platform SDK will assist with creating this image, which is necessary for Dreamcast; you can just burn it onto a writable CD.
00:08:50.959 I also have a modified Dreamcast that allows me to use SD cards instead of discs. When porting projects from Dreamcast to Wii, the goal is to use the same Ruby code across both platforms.
00:09:01.760 This can be achieved by ensuring that the Ruby API remains consistent, while the underlying C code must differ due to platform variations.
00:09:11.360 The libraries between Dreamcast and Wii provide different functions and data types, making it necessary for the C code to be adapted for each platform.
00:09:21.120 Sticking to common features such as screen resolutions is crucial, as each console can have many different video options. Settle on one common resolution to avoid unnecessary complexity.
00:09:32.920 Also, sticking to common interfaces simplifies the process. For example, while Wii features motion control, I chose to use a GameCube controller as it has more in common with the Dreamcast controller.
00:09:44.160 Now let's discuss some challenges I faced, particularly with the Dreamcast environment: many development tools assume usage of a Windows machine with an Intel processor.
00:09:54.479 While it is possible to run tools on other environments, such as Apple Silicon, porting 32-bit Intel Windows applications to an M1 MacBook can be challenging.
00:10:01.199 Additionally, my recent move from Adelaide to Tokyo caused issues, as I packed up all my Intel machines, which made the situation more complicated.
00:10:11.839 Moreover, many of the development tools I had were from 2003 to 2005, which resulted in numerous broken links, but thankfully, I found resources on archive.org.
00:10:23.160 Many tools are distributed as binary only, with no source code available. Therefore, tracking down the sources of problems can be very difficult.
00:10:30.079 Also, a lot of these binary-only tools are unsigned or outdated, meaning they may not run correctly, adding to the difficulties of debugging.
00:10:41.159 I encountered a lot of obscure issues that were hard to diagnose, as every bug is mysterious until identified. This led to a significant decision not to proceed with presenting directly from the Wii.
00:10:50.760 Additionally, the debugging process is complicated on actual consoles, providing little visibility into internal operations.
00:11:03.080 Setting up a proper debugging environment has proven difficult; I attempted to set it up multiple times without success.
00:11:13.720 Now, let's highlight some changes I had to make in C code. These were primarily header and platform-specific changes.
00:11:23.560 The exact details might not be crucial, but many changes were necessary in the C code, reflecting a considerable amount of adaptation for the project.
00:11:34.879 Interestingly, one notable change involved using the Chaos library's drawing functions compared to those provided by libogc for the Wii.
00:11:45.240 The Dreamcast approaches handling pixel placements at a finer level while the Wii relies on a coordinate-based system using column and row specifications.
00:11:55.639 Additionally, on the Dreamcast, each pixel is packed in a 16-bit format with a ratio of 5 bits for red, 6 bits for green, and 5 bits for blue.
00:12:05.520 In contrast, the Wii encodes pixels in a YCbCr format, based on the historical method used in black-and-white television signals.
00:12:16.240 This adds complexity to the image processing since the Wii packs multiple color values into a single space, making it a challenge to manage.
00:12:27.520 After all these changes, you might wonder what modifications were necessary within the Ruby code itself. Fortunately, there were minimal adjustments required.
00:12:40.280 I removed certain methods that were exclusive to the Dreamcast and adjusted the class name in a few instances. Instead of the P method, I implemented a new method, print_message.
00:12:51.000 On the second page of the adjustments, I also changed how the resolution worked, switching from 640 x 480 to 320 x 480.
00:13:00.920 This meant that calculations involving horizontal positioning had to be halved as well. I also resolved a minor bug noted in the code that caused unexpected issues on the Wii.
00:13:11.120 Now, it's demo time! Will it work? I'm not very confident, but let’s see.
00:13:23.880 Good, things seem to be going okay.
00:13:32.000 Here’s my video capture from the Dreamcast version, which I demonstrated four years ago. This is not what I did this time but serves as a baseline to show you how the original game looked.
00:13:38.920 This is the SD card loader screen, and now I'm booting the actual game.
00:13:45.520 Here it is; the game works in this manner on the Dreamcast.
00:13:54.040 This is the baseline from four years ago, and I also scored one point for deleting one line of code. Now I'll connect the Wii.
00:14:01.920 Please recall how it looked on the Dreamcast previously. This is the replacement boot screen on the Wii, allowing me to proceed directly into my applications.
00:14:14.040 Here comes the moment of truth. If this looks like what you saw on the Dreamcast, then that's a success. And... we go!
00:14:26.960 Oh! Let me play until I can score and erase another line.
00:14:39.839 There you have it! I scored 100 points, thank you!
00:14:48.160 The demo worked fine on the Wii as well. Now, regarding future plans for this project, I want to address the API unification.
00:14:57.600 The horizontal resolution is currently reduced to 320, and I intend to change that to 640.
00:15:05.280 Unfortunately, I didn’t manage to get the presenter working on the Wii, but I plan to work on that in the future.
00:15:14.080 Additionally, my goal is to execute the same code across both platforms using a single source, generating binaries for the Wii and Dreamcast by changing parameters.
00:15:22.760 In summary, cross-platform development is feasible! The Ruby code did not require significant changes, as most adaptations were achieved through the C code addressing platform differences.
00:15:40.480 However, debugging remains a significant challenge, especially when navigating international moves and presenting concurrently.
00:15:50.320 I want to take a moment to express my gratitude to the mruby developers, the devkit pro team, as well as the Simon game engine Discord server.
00:16:00.480 There’s a wealth of useful information available for anyone looking to work with Wii, and I’d like to share the links at the end.
00:16:10.000 Also, this is the source code for my demo game, specifically the Wii version. Thank you very much for your attention.
00:16:20.000 Now we will move into the Q&A session. Please feel free to ask any questions you might have.
00:16:30.000 Thank you for your presentation. I'm curious if there are any plans to port mruby to more modern consoles like the Switch or 3DS.
00:16:39.679 Currently, I do not have specific plans, although I know others have ported mruby to the Switch.
00:16:46.799 I believe there was a past presentation on that topic, and I'm open to exploring that possibility in the future.
00:16:54.440 Regarding debugging, I found that when using the Dreamcast, I could utilize an emulator that allowed console output to print debugging information.
00:17:03.360 Unfortunately, I’m not aware of any equivalent emulators for Wii that allow for debugging in that manner.
00:17:10.000 So, I primarily use print statements in my code for debugging on the Wii.
00:17:16.600 I know there are tools that support remote debugging, but I haven't had success using those.
00:17:24.559 In short, debugging on consoles is tough, and I’m working on finding better solutions.
00:17:32.679 This session is almost concluding, so if anyone has any last questions, feel free to ask.
00:17:43.639 I appreciate everyone being here today. It’s reassuring to know that many people are interested in this topic.
00:17:55.279 Thank you very much for participating, and feel free to connect with me after the session.
00:18:06.399 With that, we will wrap up this meeting. Let's take a short break before the next session, which will start at 2:25.