The Blog

of Demilade Sonuga

Writing a game from scratch (no game engine, no OS)

Prologue · 8 min read

2022-10-20

Last Edited: 2023-07-17

Hello there. We're about to go on a fun ride, an adventure, an ecstatic experience. But before we do, I would like to introduce myself and what this is all about. I'm Demilade Sonuga, a computer science maniac addicted to code. A few months ago, I had an idea of building a game from scratch in my favorite language, Rust. ...

Getting Started I · 17 min read

2022-10-22

Now, before we can get to the fun stuff, we first need to do some setup and configuration. If you don't have a rust compiler, download one from (https://www.rust-lang.org/tools/install). Create a new Rust project and open it in your favorite text editor. ...

In the Beginning is the BIOS · 21 min read

2022-10-24

What is a computer, exactly, and how does it operate? What is the sequence of steps that were taken before these words you're reading got on the screen? You pressed the power button, then what next? Your OS logo showed up, and in a few seconds, you were looking at your desktop wallpaper. But how was it ...

Getting Started II · 32 min read

2022-10-26

In the previous post, we learned a few things about how the computer starts up and about how our entry point will eventually be called. We need to replace our `main` function in our `main.rs` file with an `efi_main` function. ...

Printing Hello World · 41 min read

2022-10-29

In the previous post, we created a working efi app that does nothing. Now we're going to print "Hello World!". At this point, your `main.rs` file should be looking like this: ...

A Few Things About Computer Graphics · 9 min read

2022-11-01

So far, we've printed "Hello World", and while that's nice, for a game it's not good enough. Printing text is not all we're doing here. We also need to draw graphics. Before we proceed to the UEFI-specific stuff required to do that, let's take a quick detour to understand some things about computer graphics. ...

The Graphics Output Protocol I · 31 min read

2022-11-04

In the previous post, we learned a few things about how graphics are displayed. Now, we're going to take our first steps to getting graphics on screen. ...

The Graphics Output Protocol II · 20 min read

2022-11-07

In the previous post, we took our first steps to modeling the GOP. At this point, your code should look like this: ...

The Graphics Output Protocol III · 46 min read

2022-11-10

Now that we've modeled the GOP, we need to continue with our game. Our aim right now is to check out what's there, see what the GOP has available for us, then use that to come up with a way to draw graphics on the screen effectively. ...

The Graphics Output Protocol IV · 113 min read

2022-11-13

The remaining steps left on our list to figure out graphics are: 1. Figure out how to change the mode to a graphics mode with the GOP. ...

The Graphics Output Protocol V · 47 min read

2022-11-16

We're finally on our last step to drawing graphics on screen: ...

Printing Hello World Again I · 36 min read

2022-11-19

To get printing text again, we have to use the raw pixels of our graphics mode. But before we proceed, we must first ask ourselves this question: what is text? ...

Printing Hello World Again II · 40 min read

2022-11-22

In the last post, we pinned down our font for the letters 'A' - 'Z'. If you got stumped along the way, the full source for the last post is ...

Printing Hello World Again III · 61 min read

2022-11-25

It's finally time to print "Hello World!" in our graphics mode. ...

Refactoring I · 55 min read

2022-11-28

In the previous posts, we did a lot. We modeled the Graphics Output Protocol, switched to a graphics mode, designed a font and printed "Hello World!" with our font in our graphics mode. But, at this point, there are a lot of things that are just off with the code. ...

A Few Things About Safety In Rust · 11 min read

2022-12-01

In the previous post, we cleaned up some of our code but there are still some problems with it that could be solved with a few changes. To solve those problems, we need to understand a few things about safety in Rust. ...

Refactoring II · 34 min read

2022-12-03

Unsafe is everywhere in our code and that is not the Rust way of doing things. Rather than scattering unsafe here and there, we create safe abstractions which internally use unsafe code, whose safety has been manually verified. ...

Refactoring III · 70 min read

2022-12-06

We've done a lot of refactoring but there's still more we need to do. ...

A Few Things About Bitmap Images · 10 min read

2022-12-09

Soon, we'll finally start drawing images on the screen but before we do that, we first need to understand some things about the bitmap file format, which is the format we'll be dealing with. ...

Drawing Bitmaps I · 9 min read

2022-12-12

In the previous post, we learned some things about bitmaps. Now, we're going to draw them. First, download the image we're going to draw from ...

Drawing Bitmaps II · 50 min read

2022-12-15

The bitmaps we're going to be working with consist of 4 sections: ...

Drawing Bitmaps III · 38 min read

2022-12-18

Onto our final steps to draw block.bmp: ...

Refactoring IV · 52 min read

2022-12-21

In the previous post, we finally got block.bmp on screen, but in the process of doing this, we convoluted our `efi_main`, again. What we're going to do now is to rectify that. ...

Automating The Build Process · 20 min read

2022-12-24

I'm sure that by now, you would have gotten tired of typing in these commands to run the game: ...

Animating Bitmaps · 13 min read

2022-12-27

Before we can get on to animating bitmaps, we first need to ask ourselves: what is animation? ...

Panicking I · 20 min read

2022-12-30

We've gone a long way in this project. So far, we've been able to animate a bitmap on screen. We could just keep going on right now to the next thing but that's not really a good idea because there's a major thing we're missing out: that is sensible panic behavior. When a panic occurs, the computer goes into an eternal loop, without giving any information on why the panic occurred: ...

Panicking II · 30 min read

2023-01-02

One potential way of resolving the uselessness of our panic handler is to try to extract the string chunks and arguments from the struct directly and print them one by one. This won't work because, as it is clearly in the ...

Panicking III · 55 min read

2023-01-05

If you got stuck while putting down your digit descriptions in the font, you can get them from the ...

Refactoring V · 69 min read

2023-01-08

In the process of pulling the screen reference out of `efi_main`, we introduced a lot of unsafety in the code, which exposes us to more opportunities to screw ourselves up. We start our next refactor by hiding this unsafety behind a safe interface. ...

The Game Scene · 25 min read

2023-01-11

It's finally time to draw up our game on the screen. ...

Getting Ready For Event Handling · 44 min read

2023-01-14

We have the initial game setting on the scene now, but it's still just a dumb picture. For our game to become a real game, it must be able to animate believably when we press certain keys. When the right arrow key on the keyboard is pressed, the paddle should move to the right. When the left arrow is pressed, it should move to the left. Once the game has started, the ball should keep bouncing around the screen until it leaves the screen (in the case of a lost game) or all blocks have been broken (in the case of the game won). ...

A Few Things About Interrupts · 17 min read

2023-01-17

Interrupts are signals sent to the processor telling it to immediately attend to something else. To understand x86's interrupt system, there are three main players we look at: ...

The Interrupt Descriptor Table I · 12 min read

2023-01-20

In the previous post, we took a brief look at the pieces of x86's interrupt system and how they fit together. We looked at the IDT and saw how it is the mechanism used to determine what to do when an interrupt occurs. At computer start-up, the UEFI firmware sets up its own IDT which it uses to handle its timer services. Now that we've exited the Boot Services, we can set up our own IDT. ...

The Global Descriptor Table I · 26 min read

2023-01-23

Memory management is an integral part of OS development that we've managed to escape. This is mainly because of the UEFI firmware which handled a lot of memory stuff for us. This is still one aspect of development we're just going to skim because we don't need to handle it in this project but now that we've encountered the GDT, we need to step back and take a quick look at this subject. ...

The Global Descriptor Table II · 31 min read

2023-01-26

In the previous post, we took a look at the GDT in a lot of detail. At the end of the post, you were supposed to come up with a Task State Segment Descriptor describing a segment starting at address 0x123fc and is 13Kib in size. Before we get on to modeling the GDT, let's quickly look at one way of doing this: ...

The Global Descriptor Table III · 25 min read

2023-01-29

If you came up with the descriptors for the code and data segments, I'm sure that they would be just long strings of digits the meaning of which is not immediately apparent. To remedy that, let's take a quick look at bitwise operations. ...

The Global Descriptor Table IV · 41 min read

2023-02-01

The last thing we need to model is the segment selector. Model it yourself now. ...

Refactoring VI · 17 min read

2023-02-04

We've gotten the GDT in code. Before we move on to the Task State Segment and the Interrupt Descriptor Table, we have to do a little refactoring. ...

The Task State Segment · 51 min read

2023-02-07

The next step on our list before we can get back to interrupts is to set up a Task State Segment. ...

The Interrupt Descriptor Table II · 30 min read

2023-02-10

When we began our first steps into interrupts in the ...

The Interrupt Descriptor Table III · 22 min read

2023-02-13

In the previous post, we started modeling the IDT but stopped at the problem of determining how to appropriately associate different types of service routines with entries. This is what we're going to resolve now. ...

The Interrupt Descriptor Table IV · 41 min read

2023-02-16

We're almost done with the IDT model. All that's left is to add functions for setting entry fields and setting up the IDT. ...

The Interrupt Descriptor Table V · 14 min read

2023-02-19

In this post, we're going to set up the IDT. ...

Some Important Exceptions · 19 min read

2023-02-22

In this post, We're going to take a look at some exceptions easy to trigger and others that we actually have to pay attention to and we'll further check out the interrupts mechanism with the IDT. ...

The Programmable Interrupt Controller I · 22 min read

2023-02-25

We've finally reached the last player in the interrupts game: The PIC. This component is essential in dealing with events from the timer and the keyboard. ...

The Programmable Interrupt Controller II · 14 min read

2023-02-28

To see hardware interrupts in action, we're going to start with the timer. ...

The Keyboard Interrupt I · 6 min read

2023-03-03

When a key on the keyboard is pressed, two things occur: ...

The Keyboard Interrupt II · 47 min read

2023-03-06

In this post, we're going to start getting our keyboard driver together, the code that will interpret the scancodes read from port 0x60 during keyboard interrupts and translate them into key events. ...

Thinking Through Event Handling · 5 min read

2023-03-09

In this post, we're just going to think through exactly what we need to get event handling to work. ...

Event Handling I · 27 min read

2023-03-12

Based on the requirements covered in the previous post, we're going to begin constructing a scheme for event handling. ...

Heap Memory · 12 min read

2023-03-15

The first stop on our journey to event handling is creating a heap. But first, let's stop and ask ourselves: what exactly is a heap? ...

Heap Allocator I · 13 min read

2023-03-18

Now that we have a heap, we need an allocator to manage its memory. The main role of the allocator is to keep track of free memory. When we need heap memory, it's the allocator we ask. If there is enough memory, the allocator marks it taken and gives us a pointer to it. When we don't need heap memory anymore, the allocator marks it unused. So, the allocator is just a memory bookkeeper. ...

Heap Allocator II · 47 min read

2023-03-21

In this post, we're going to implement a linked list allocator. ...

Heap Allocator III · 34 min read

2023-03-24

In this post, we're going to be testing our heap allocator. ...

Box I · 4 min read

2023-03-27

Now that we're done with the heap allocator, the next thing on our list is the Box. ...

Box II · 14 min read

2023-03-30

In this post, we're going to implement a Box. ...

Box III · 32 min read

2023-04-02

In this post, we're going to test the Box. ...

Interlude A: Some Potential Problems In The Project · 21 min read

2023-04-05

Now that we've gotten down our heap allocator and Box, we're going to take a step back and take a look at the forest instead of the individual trees (and some potential problems with this forest). ...

Vec I · 3 min read

2023-04-08

The final thing on our list before we can get on with event handling is the vector, and we're finally here. ...

Vec II · 37 min read

2023-04-11

In this post, we're going to implement a vector. ...

Vec III · 17 min read

2023-04-14

In this post, we're going to test our vector. ...

A Few Things About Trait Objects · 14 min read

2023-04-17

Now that we've gotten down the utilities needed to continue with our event handling scheme, it seems like the next thing we need to do is continue working on the event handling scheme. But we can't do that because one more thing is missing from our toolbox. ...

Implementing Trait Objects I · 29 min read

2023-04-20

This is the last thing we need to complete before we can fully get on with event handling (I promise this time). In this post, we're going to be implementing boxed trait objects for functions. ...

Implementing Trait Objects II · 11 min read

2023-04-23

In this post, we're going to test our function trait objects. ...

Event Handling II · 25 min read

2023-04-26

In this post, we're going to finish implementing the event-handling scheme ...

Event Handling III · 17 min read

2023-04-29

In this post, we're going to test the event hooker. ...

Event Handling In Action · 20 min read

2023-05-02

In this post, we're going to see the event hooker in action. ...

Refactoring VII · 12 min read

2023-05-05

Finally, we have an event-handling scheme in place. We're almost done with the project. But before we get on with the rest, let's do some refactoring. ...

Refactoring VIII · 21 min read

2023-05-13

There are a lot of improvements that could be done to the code to make it generally better, easier to read, and more organized, but we won't be doing that at the moment. In this post, we'll be focused on figuring out how to go about removing the many instances of unsafety in our code. ...

Once · 52 min read

2023-05-20

In this post, we're going to implement a Once. ...

Mutex · 17 min read

2023-05-27

In this post, we're going to implement a Mutex. ...

Refactoring IX · 89 min read

2023-06-03

Armed with a Once and a Mutex, we can now refactor away all those mutable statics. ...

Sherlock Holmes And Deadlocks · 55 min read

2023-06-10

If you run the game now, all you'll get are a bunch of double fault errors. In an earlier post, it was suggested that the reason we could have such non-deterministic errors is because of race conditions. With the refactoring of the previous post, we can be confident that we have eliminated any such race conditions now. But then, why is the code still not doing what we expect it to do? That is the question that we'll resolve in this post. ...

To Create A Game · 19 min read

2023-06-26

We're almost there. According to the list laid down in the prologue, we've completed nine out of twelve items in the creation of this project. And while that's all wonderful, we still do not have a game. All our work did in the preceding posts was to set up the infrastructure that we'll use to make the game, not the game itself. So, that's what we'll dive into in this post. ...

Some Mathematics I · 32 min read

2023-06-30

In this post, we're going to begin infusing the game with physical laws. ...

Some Mathematics II · 68 min read

2023-07-29

In this post, we're going to get to the ball's motion and interaction. ...