If I could get this again talking about it, it's a got dreamcast stuff with GCC last year
he had some Fortron or whatever code run on the VMGOS let's see now it's what we've done
with it.
Uh-huh, this is the theme.
Okay, so so I'm here on behalf of the Sega Dreamcast community to talk about a lot of
the stuff that we're doing with GCC, um, I was here last year and last year was kind
of getting infrastructure set up and getting a bunch of new languages on the Dreamcast.
This year, um, I'm happy to say that we've done something with them, we've done a lot
of stuff with them.
Um, first of all, what is the Sega Dreamcast?
It was a sixth generation console, not a fifth one, not like Nintendo 64, here that
a lot.
Um, it was to directly compete against the PlayStation 2 GameCube and Xbox, which came out
a little bit later, uh, it launched quarter four, 1999 and then it was discontinued, uh,
I guess it's not up there, March 31st, 2001, so it had a very short lifespan and it was
considered a commercial failure as you'll see, but it doesn't mean anything to us, um, it
has a Hatachi SH4 CPU and that's what links us to GCC as you'll see, that's why we're
here.
GCC was the only compiler that ever supported the Super 8 architecture other than, uh,
Hatachi specific ones for a small amount of time and nowadays, everything's done on GCC
for SH, um, there's several communities that still use it and there was a form post about
asking if L of M would be interested in the back and then they said, no, the super H is
a toy architecture, so they're right about that.
You'll see how cool the toy is.
Um, it has an imagination power VR2 GPU, which is the previous iteration of what wound up
in the iPhone actually, so that whole line, the power VR from imagination, one of hugely
successful and mobile, um, it had 16 megabytes of RAM, 8 megabytes of video RAM, uh, proprietary
media format called GD ROM, but as you'll see, it can still read CD ROM, that's why we're
able to do home brew on it, um, it came online ready with a built-in 56k modem.
Nowadays, we have hardware models that will let you dial into Raspberry Pi, so you don't
actually have to use dial up anymore, um, and then even the memory card is cool, uh, it's
a 128 kilobite capacity flash, uh, 8 bit micro controller visual memory unit that also has
its own home brew scene.
So this was the year 2001, what happened?
So this cool platform, SEGA for saking consoles to focus on software, SEGA quits the
SEGA Dreamcast, SEGA scraps it, SEGA to halt Dreamcast production, this thing died, and
basically nobody cared about it for a long time.
But if you read the news now this year, that's what it looks like, and how did, how did
this happen?
We were covered by digital foundry the other day for, we poured grand theft auto 3 from
the PlayStation 2, well, that's from the PC, it was originally on the PlayStation 2,
to the SEGA Dreamcast, we're going to go into that.
We've had a bunch of other, uh, really exciting successful ports, uh, we were covered by
hack-a-day, um, Duke Nukem 3D was, uh, impressed its creator that we ported it to the Dreamcast,
and yeah, we've had a lot of fun this year.
So, uh, believe it or not, people still make Dreamcast games, and Dreamcast home brew, and
people port all kinds of crazy stuff to the Dreamcast, because it's actually pretty powerful,
but it's still embedded, um, I think that appeals to a lot of people with it, and it just
has a whole lot going for it, and it's an entirely open ecosystem too, as you'll see, that
kind of draws people in, um, why did they do it?
Like I mentioned, I think the same kind of audience that likes Raspberry Pi development or embedded
systems, uh, I think they're drawn to this, because it's, uh, it was very powerful for
its time.
It's still pretty powerful, and as you'll see, we're doing a lot of stuff on here that maybe
has no business running on its SEGA Dreamcast, but we do it anyway, and, uh, as you'll
see, it works out pretty well.
You can treat it kind of like, uh, on the lower end, you can treat it kind of like a weaker
PC on the higher end, you can optimize for it and go to town on it and get really impressive
results.
At this point in time, we have thanks to you guys, modern compilers and tools, so part
of the appeal is you can develop for this extremely retro platform with modern GCC-142.0, as
you'll see, and be on the bleeding edge of that stuff.
Um, we're in compiler explorer, believe it or not, which makes it fun.
I don't even remember X86 assembly anymore.
I just, look at Super H, and, uh, that's how we optimize a lot.
As I said, you can run custom code with no modifications on this thing.
That's how it got extremely popular is you can just burn a CD and play it.
Nowadays, we have SD cards, we have hard drive mods.
There's a little bit more that you can do now than just burn CDs.
Has cool toys and peripherals, has light guns, it has maracas, it has fishing controllers,
just a lot of fun toys with it, and it has, at this point in time, a pretty thriving
home-view community, and so does the memory card.
Um, so this is a run through of our SDK that I work on.
I'm a contributor to it.
It's called Calistios.
It's been around for about 20 years, but it didn't start to get really good until a lot
more recently, and drop people into work on it.
It's pretty much custom, uh, a custom mini operating system.
It's a unicarnal.
Uh, technically, I think it's considered a library OS.
You link to our kernel, and by default, your applications are on kernel space, which is
both good and bad.
You can do some really fun stuff with it with C++20 and kernel space, and yeah.
We have a, we sit on top of new lib for, uh, file IO, date time, lib-c kind of stuff.
We also implement a whole lot of lib-c and politics APIs ourselves, just, because the
more complete our API coverage is the easier it is for people to target a platform, the
more course we get.
We have a really good virtual file system where you can just use C standard file IO, file
IO, or C++, and it just works, and depending on your virtual path, they can go to the
memory card, it can stream off the network, et cetera.
We have IPv6 stack on it, uh, we have drivers for almost everything the Dreamcast has inside
of it hardware-right-wise.
We have texture tools, asset utilities, stuff like that.
We have a whole bunch of examples that are how I learned to program in general, actually.
I grew up using the examples that's why I learned C, so now I work on them, it's kind
of cool.
Then we have add-ons and ports, like if you know OpenGL, legacy OpenGL, you can
code for the Dreamcast, we have that, we have SDL, we have RayLid, we have OpenAL, we have
a pretty rich set of libraries, obviously the higher up the abstraction chain, you get the
more you're sacrificing performance, and there's a trade-off there, depending on the kind
of game you want to put on there, but I mean we have game engines written entirely in Lua,
if they're just interpreted script, interpreted scripts that are pretty cool, and games
written with those.
We actually had a game jam, but we had 24 submissions this year, and several of them
were written in Lua by people who have never programmed for like these embedded retro consoles
before, and it was accessible enough that just someone writing Lua scripts for like,
I don't know, what engine, love 2D or something, they could come over and be productive
and contribute to a game jam and release a game for the Dreamcast, I thought that was pretty
cool.
Our tool chains, that's the version of Bignitils, 243-1, GCC, we have 142.0 is currently
what most of us are using, although we have a preview tool chain configuration, that's
just always on the tip of 15 that we make sure that no one breaks anything, or that everything's
good, and everything looks great right now.
GDB15.2, in terms of language support, we have up to C23, partially supported, basically
in terms of core language, whatever GCC supports is what we have on the front and partially
C++26, we have very good standard library support for both of them.
We have from last year you might know that we have like standard A sync, we have threads,
we have, we have cover teams and C++, a lot of really powerful things, we have objective
C, but we have yet to complete our foundation port.
We have someone by the name of Luna actually began work on Cliftheos bindings to D using
the GDC front end for the D-line, and that's pretty cool, and then we have rust to some
extent.
It's a work in progress, and there are kind of two ways you can use rust on Dreamcast,
but I'll get into that.
This is my Dreamcast set up yet again, I just want to share it.
It's a little special, I've modded it for 32 megs of RAM so that if I'm profiling a game
that's like close on the RAM limit, and I need a little bit of extra RAM and wiggle room,
and some people are trying to get stuff on the Dreamcast that they just need more RAM to
start with, even if you're not in 16 megs yet, it's nice to not just crash or throw an
exception on out of memory or return null from malloc, that's why it's pretty cool.
Mine has a hard drive, a lot of people are doing that now.
You can have that with the disk drive, I have an Ethernet adapter, that's how I stream
stuff off the network, and that's how I generally test.
I submit binaries over the network, and it's got a bootloader that will play the elf off
of the network.
I have a custom BIOS, custom fan, custom power supply, and I plug it into a Wi-Fi wall
outlet, so I can have this thing ready to go on my Jenkins build server that will turn
it on automatically and run CI on it, so yeah, little crazy.
Like I said, since last time you guys released GCC-142.0, when this happens, we like to have
a release party, we like to say, hey, day one, the Dreamcast, you can come, you can come
use the latest GCC on Dreamcast, so yeah, we had a day one party with that, we play with
the new features.
I will say, we are getting better performance now on the latest GCC-143-1999 processor,
that's pretty exciting.
We have fewer icees, but we still have a couple of knocker live up that.
We do have one thing that's a little bit regress that I should mention.
We do use O.S.
Quite a bit in our community, and I'll get into that to sit into RAM, because we're
putting things from PCs, bigger game engines these days, we use O.S. a lot more, and
it looks like the binary size while they're getting faster, are getting a little bit
bigger since GCC-12.
Okay, absolutely, thank you.
Okay, awesome.
That's important, let's put some books.
Yeah, we absolutely do.
Okay.
We need some examples.
Okay.
Absolutely, we'll get on that.
Thank you, I appreciate it.
Oh, and then you guys declared implicitly, declared C functions, thank you.
Thank you so much.
I know everyone was not happy about that, but I was, fixed a lot of bad code, especially
with LTO.
I thought that was a good move, a lot of people were not happy, but I was.
C++ 23 features that we immediately got started playing with.
Look guys, we got a new standard output mechanism, standard print, standard printline from
print.h, well not.h, just print.
I think they got it from Rust or Python, doesn't that look like syntactically how their
print mechanism works?
We also got deducing this, which is a little complicated, but it helps with representing
the curious, free recurring template pattern in C++, and another trick that allows
you to do that you could never do before, is it allows you to recursively call a lambda,
which you couldn't do before because you had to pre-declave a lambda, and yeah, you couldn't
identify it.
So that fixed that, and we can use all that on the Dreamcast now, which is pretty cool.
So that's the output running on the Dreamcast.
Next, what we start playing with is in our community, most people aren't writing assembly,
but a lot of the people who are at the upper-actual ons of performance, they either write
assembly or there's a fast math library that's been floating around, did everyone just
copy paste into their projects, and we took a step back, we're like, okay, how fast is
this in line assembly here?
And so what we have here is this mathematical fast-inline assembly that's being used all over
the place in the community in different ports.
For example, this is in the OpenGL back end for our OpenGL driver.
It's fast-multiply accumulate.
The Super H4 was apparently one of the first ones to have a hard work-sarrated F-Mac that
wasn't for a DSP, and it's only in approximation.
You have to either use inline assembly to do an F-Mac, which is A times B plus C.
That's all it is.
The standard C-functioned F-M-A-F is similar.
So we have two scenarios.
We have the inline assembly thing that everyone loves to use in our community, and then
we have an inverse square root, which I don't know if you guys have heard of it, but
Quake 3 had this famous, I don't know how to describe it, integer bit math trick that
allowed it to do fast inverse square roots, and there's one instruction on the Dreamcast.
So that's another reason we do inline assembly.
The multiply accumulate is another one, and then we have this instruction that is a floating
point sign cosine pair.
You pass it in angle, and then in two different registers, you get the sign and cosine,
and you can extract that.
That's also an approximation.
So to get the compiler to use these, you have to have a fast math enabled for obvious reasons.
You don't want to apply to cross the board, and you have to have two flags enabled that
independently enabled those instructions, the inverse square root and the combined sign
cosine.
So we put it to the pass.
We made a simple example.
This is what I see all the time.
And this is what I saw in our OpenGL driver.
We had a static loop that was looping over some pre-set amount of vertices.
It might have been four because it was a quadrilateral, or no, that would be six, sorry.
So basically, if we define the pre-processor fmax0, we're using this fmax, which is just
we're letting see, inline that and do what you can.
Otherwise, we're using this thing, that everyone's copypacing in their code base, which
is faster, one instruction, right?
So we finally test it out, and what do you know, this is see the compiler decided that
it can factor out the multiplication, and that became a constant.
And here, it loop on rolled, and it became something much worse.
But loop on rolled, the f-map, which didn't even ever have to happen, and yeah.
So you lose a lot of performance.
So this is with a bunch of tweaks.
This is Mario 64, not going to let it play for too long.
We thought we'd be boring to just play Mario 64 on a Dreamcast, because it should run a
Dreamcast.
So this is it at 60 frames per second, uncapped, to make it more interesting.
So yeah, it runs pretty well at uncapped frame rate.
There is a little visual glitching on Mario's face.
That's an issue we actually fixed, but I kept it, because I think it's endearing, that's
Dreamcast, Mario.
Something I thought was really cool is one day I was playing with the new compiler version,
and I was like, I wonder what happens instead of C++ if you don't have a time zone
database.
So I tried to access it, and I had a time zone database on a Dreamcast.
And I was like, how did this happen?
I could print and walk at time zone database, and it turns out that GCC build script
or something, added where it will go online and download the time zone database and embed
it in a read-only RAM, or I'm sorry, the read-only segment, and yeah, you actually
wind up with the time zone database, and you can turn it off to if you don't want it
on embedded.
So that was, we thought that was really cool.
This is our Sonic Mania port, which does a whole bunch of things that are pretty common
for the community.
This is way too big to fit into RAM initially.
We cannot do anything other than ODOTS initially to fit into RAM.
So what we do is we ODOTS or ODOTS, sorry, we owe three all of the critical things, like
the renders, the graphics, mathematics, the physics, and then we OS everything else, and
we kind of mix them to get the best of performance and size.
And typically when we do that, we can get the performance as well as running with O3 on
everything.
That's pretty nice.
We use LTO a whole lot in the Dreamcast community.
I always tell people to use it if you're watching remotely, you should definitely be using
LTO.
It's like free frame rate gains just for a little bit of extra compile time.
And yeah, this is the console logging from the network from Sonic.
We got a little fun with C++23, and we made an IRQ handler that can basically be invoked
from any generic, callable C++ type by making a bunch of concepts that allow you to basically
constrain a template argument, based on whether it's a callable with the correct syntax
or not, and then use any generic callable as a IRQ handler.
This is our Dream64 port to the second Dreamcast, which is superior to the actual commercial
game in a lot of different ways.
We looked at 16 simultaneous dynamic lights.
We have bump mapping at target 60 FPS.
There's no lighting on the original game.
There's no lighting on the stingery release.
So this has all been added just for Dreamcast, and this the author Jan Martin prides himself
on he likes to rip in line assembly of his code.
He just likes to do it in C, like to prove I can achieve this in C, and he absolutely
can.
Finally, the one that I want to talk about is our grant that thought of ports to the
three ports, the second Dreamcast.
This was called impossible for like the last 20 years.
This was the selling point of the PlayStation 2.
You got a via PS2, so you can play GTA 3 because the Dreamcast isn't powerful enough.
So that was BS.
We're going to look at a little bit of code for it.
It was a lot of work.
It was done by a really talented team, and it was just amazing.
The whole Dreamcast community came together and made this happen, and it was beautiful.
And we had like a hundred players testing, and it was just beautiful.
This is just drawing sprites, okay.
This is a crazy hybrid C++20, abusing pre-setching loop on rolling code base that is just
mixing modern and old and inline assembly, and it's kind of glorious.
It's kind of beautiful.
For rendering primitives, there's two layers deep of lamb does just to do that, but then
we're also being extremely careful with pre-fetching the cache and doing all that.
Believe it or not, just for 2D, these lights, the bloom around it, the lens flare here,
the rain, those are all just flat textures.
So it's actually important that 2D rendering was pretty fast.
This is something I made on the team.
This was born because I wanted to profile the game, but I was too lazy to figure out how
the UI works, and so I decided to render it to the VMU.
So we spawn a thread, a standard thread, and C++11, and we're able to do a bunch of cool
stuff with it.
Relatively easily, that's all the code that took to make that real-time debugger, and we
actually released with it.
Next, I want to talk about which, in my opinion, was the craziest part of this entire project
was the Transform and Lighting Loop.
It's the most expensive part of any Dreamcast game, because they decided that the Dreamcast
CPU would be the thing processing and transforming all the vertices, whereas like the
PlayStation 2 used the co-processor.
So this has to be very fast.
Just to quick look at it, what we've done is this is just transformation.
Notice we have a bunch of non-template type arguments that are Boolean.
This allows us to basically compile time-generate versions of this where we use if-constex
for, and we can compile out the branches, right?
So there are multiple, instantiations of this loop.
None of them have branching in them, and we take the variation.
We choose the variation at one time that's basically best suited, same with, if we're
clipping or not, we're pre-fetching, and yeah, I think that was, it's a little worris
being able to do that on a Dreamcast and mix all those different constructs.
This is what it turned out looking like.
The audio was a little messed up in this capture, because it was earlier in development,
so I just turned it off.
But you can see that obviously it was possible to run Grand Peptata 3 on the Sega Dreamcast.
It looks pretty good.
It doesn't run as well as the PlayStation 2 yet, but we're still working on it.
Has dynamic lighting.
It has a pretty high polygon count for that era.
It has a lot of special effects, and yeah, it was pretty cool.
So what about other programming languages?
Sorry, I went too far.
I just ruin the supplies.
What about other programming languages?
Well, we have a couple that are coming up.
We have some that aren't complete, but does anyone know what this is?
This is the language in case you need to do some government contracting for your Dreamcast
or defense programming.
But we have a bunch of people who are excited to use this on the Dreamcast, because this
is apparently related to VHDL, or it's a lot of influence from VHDL.
We have a bunch of programmers who do that.
So this is binding to our CAPI to make open GL calls, and this is Ada.
We have the entire Ada tool chain going, are the Ada tools, Nat, and all the friends
on the Dreamcast now, and we combine it to the CAPI's, and I think that was really cool.
That was Mark, so we're very happy with that.
And there's a bunch of people who are excited to play with it.
Rust on the Dreamcast is in an interesting state, because, okay, that's intentional.
That's a benchmark.
That one is a benchmark, I promise.
It's not just bad code, but that's our polygons pushing benchmark to see how many polygons
can we push.
So we actually have GCCRS, and we have GCCRS, and we have Rust C code gen GCC, which
is the main path chosen for now, by the person doing most of the Rust work, because it's
a little bit further along.
It's an experimental code gen for the Rust C compiler that interfaces with lib GCCGIT.
We have full-sand library support with it, and it relates to cargo.
We have Tokyo Async runtime.
We have a bunch of APIs bound to it.
There are some that we've made safe, but not very many of them.
Not yet.
It requires patching for SH4.
It requires patching for a lot of different platforms.
It doesn't technically support.
So that's unfortunate, that's a little bit annoying.
We've been getting a lot of good use from it, but there are definitely some strengths
that we're looking forward to from GCCRS.
That's one of them, is it will actually fully support the platforms we have, and there's
another issue, actually, that we've encountered.
Performance has been really good with this approach, but when it really matters in that
transform and lighting loop, this is the critical loop in unsafe Rust.
We're submitting polygons extremely quickly.
You send the primitive header, which just tells the GP what kind of polygons it is, and
then for all the polygons, you map to a special buffer that submits vertices to this called
a tile accelerator extremely quickly, and you basically commit the vertex.
You map to the buffer, fill in the vertex, and commit it.
And the way you commit is with, right now, in our SDK, it's with the prefix.
The prefix instruction in line assembly, that's how the SH4 works.
You launch a prefix with the store queues enabled, and it will basically copy extremely quickly
32 bytes of data, which happens to be a vertex size.
What we have to do with the non GCCRS Rust configuration, well, notice this is always
inline assembly.
They don't have support for SH4 technically, so we can't use inline assembly, so we have
to do something a little bit different that you wouldn't think would matter that much,
but it does.
We have to wrap it in an actual function call, okay.
So think about having to call a function 2 million times a second when this was just one
instruction.
So actually that hurts, that hurts us, well, the statistics aren't there, oh yes, there.
3 million polygons per second peak with C right now, 2.4 with the Rust bindings, doing
literally the exact same thing, just because of that function, that function call overhead.
So that's something that GCCRS would definitely help with, so looking forward to that.
That was kind of the survey of what we've had going on.
I want to thank everyone who's contributed to GCC, who's allowed all this to happen,
because it's from everyone's work, that we even can have nice things on the Dreamcast still.
There's a link for how you get started with Dreamcast development, and I want to mention
that we're not the only community that does crazy stuff with GCC.
Notice, PlayStation portable, Sega Saturn is SSH2, there are CPU cousins, with Dragon and
10S64.
They're all on the latest GCC-14, so you guys are powering a lot of home brew, a lot of
home brew consoles, and that we definitely all appreciate that, and we're language enthusiasts,
so we definitely use a lot of what GCC has to offer.
That was it for the presentation, are there any questions?
Yeah.
Thanks.
That is a really good, okay, two things, OP, who is with the lead engineer of the GTA-3 engine,
is one of the coolest people I've ever met, he supported us on Twitter and tweeted out
that he was impressed, and he always thought work on the Dreamcast, and no, we have not
been shut down.
Every day we look for the season to sit's lighter in the mail, and it hasn't come yet.
Yeah, yeah, definitely.
If you ever see this, thank you very much.
Yes.
Yes, I'm from Huntsville, Alabama.
And you show in the picture of the Dreamcast, the logo is a group, it's not a group, it's
bread.
Yes.
But in the States, the Dreamcast is a group of people.
No, in the States, it's orange, actually, yeah, it's not the same.
I have like 10 different Dreamcast, yeah, that must have been, yeah, I have a little bit
of a problem, I have a lot of them in my office, I didn't even notice that, that's
really good, that's really perceptive, yeah, that must have been, that must have been
exactly what it is.
Yeah, no, that's a good question.
Any other questions?
Yeah.
How do you import games to their, like, do you have the source?
Yes.
Where do you get it from?
Yes, so the question is, how do you import games to their, do you have the source code
to games?
Yes, we have to have something to go off of, but fortunately, just like there's a community
of us doing Dreamcast stuff, for every big game, really big games, there seems to be
communities that merge, that reverse engineer them, that decompile them, and then allow
you to import them using RAPIs and RSDKs.
So these were mostly based on decompelations and reverse engineer projects.
And there's more appearing constantly for other games.
So that's pretty nice.
Interesting.
Oh, yes.
I can just add that the reason why you're pinprinting us, that's a bluder, though, is that
it was a trademark dispute, but then an Italian company called T-Body, that T-Body
or something like that, and they had an orange squirrel, so they changed the squirrel to
a bit then.
I didn't even know the full story, nice.
Anyone else?
Okay, well, thank you very much.