DEV Community

Cover image for Old-School Graphics in C# / .Net 8, Part 1: Teaching an Old Dog New Tricks (Introducing Mode 13hx)
Peter Truchly
Peter Truchly

Posted on • Edited on

Old-School Graphics in C# / .Net 8, Part 1: Teaching an Old Dog New Tricks (Introducing Mode 13hx)

I began my journey with computers and programming during the era of 386 PCs, a time when DOS games ruled and sparked endless curiosity. I remember playing those games and wondering how they were created. It wasn’t long before I discovered Mode 13h - a graphics mode that perfectly fit within a 64kB page in 16-bit code, thanks to its 8 bits per pixel, 256-color palette, and 320×200 resolution.

Many years and APIs have passed since, but every now and then, I feel nostalgic for that simpler time. Back then, all we had was an array of pixels and an idea - and that was all we needed. I recall the breathtaking graphical demos that showcased incredible creativity, often categorized by their size. Some were only a few kilobytes but managed to display complex scenes with textures, geometry, animations, and even synchronized music.

That era had a certain magic. Many of the games of that time are legendary, and are still being ported to modern platforms and APIs today. Revisiting that period feels like embarking on an archaeological adventure - uncovering hidden treasures in the form of old code, design principles, and mathematical tricks. While reliving those times, I often reflect on the stark contrast with today: CPUs are now far more powerful than the high-end GPUs of the early 2000s, offering astounding possibilities. Yet, with all this power, we’ve lost much of the simplicity in the creative process.

To bring back the spirit of Mode 13h, I decided to create a template C# project which I named Mode 13HX. The goal was to capture the simplicity of the past while embracing modern practicality. There’s no need to limit ourselves to 256 colors or 320×200 resolution anymore. Instead, I focused on supporting more platforms (x86, ARM) and operating systems (Windows, Linux, macOS). This project provides a simple yet powerful entry point, paying homage to the roots of graphics programming while adapting to today’s possibilities.

History

Mode 13h is a graphics video mode introduced with IBM's VGA (Video Graphics Array) standard in 1987. It provides a resolution of 320×200 pixels with 256 colors, marking a significant advancement in PC graphics capabilities at the time. Due to its straightforward programming model and direct access to video memory, mode 13h became popular among game developers in the late 1980s and early 1990s. It played a crucial role in the evolution of PC gaming, allowing for more detailed and colorful graphics despite its relatively low resolution.

Technical Details:

  • Mode Number: BIOS video mode 0x13
  • Resolution: 320×200 pixels with a 16:10 aspect ratio, approximating 4:3 on CRT monitors
  • Color Depth: 8 bits per pixel (256 colors) from a palette of 262,144 (18-bit RGB)
  • Video Memory Location: Linear framebuffer starting at segment 0xA000
  • Memory Usage: 64 KB of video memory
  • Access Method: Direct memory mapping without bank switching

Mode 13HX

When re-imagining this mode, it’s no longer necessary to constrain ourselves with a limited palette or small resolution - these constraints can be easily emulated if needed. In my opinion, the most compelling aspect is the ability to directly access, modify, and manage a continuous block of pixels in memory before displaying it.

+-----------------+-----------------+-----------------+
|                 |                 |                 |
|     Frame 0     |    Frame 1      |     Frame 2     | <-- CPU writes pixels
|                 |                 |                 |    IRasterizer.Render()
+--------+--------+-----------------+-----------------+
         |
         V    
+--------+--------+        +-------------------------------+  
| OpenGL Texture  |        |  Vertex buffer                |
| (updated by FB) |        |  (with texture coordinates)   |
+--------+--------+        +--------------+----------------+
         |                                |
         V                                V
+---------------------------------------------------------------+
|                    OpenGL Rendering by GPU                    |
|                          (Draw Calls)                         |
+---------------------------------------------------------------+
                             |
                             V
                       +-------------+
                       |   Screen    |
                       +-------------+
Enter fullscreen mode Exit fullscreen mode

I chose the great OpenTK toolkit and its OpenGL bindings. The idea here is simple: setup a textured polygon (two triangles) and make sure it covers the viewport exactly while updating its texture for each frame. Technically we have the power of GPU on our side as well. This is especially useful when we need to scale the image up (or down) to match the screen resolution. The texture data we update is essentially a frame from our framebuffer!

Technical Details & Usage:

  • Base C# project: Provides examples, IRasterizer interface and direct pixel access. Built with OpenTK targeting .NET 8, tested to work on Windows and Linux. GitHub repository: mode-13hx
  • Resolutions: default is 1920×1080 (Full HD), customizable via -w, -h options, works with any resolution. Tested with 3840×2160 (4K).
  • Modes: full screen (-f) and windowed (default).
  • V-Sync Support: Enable with -v to synchronize rendering with display refresh rate.
  • Color Depth: 24-bit RGB (True Color), supporting 16.7 million colors. Each pixel uses 3 bytes (RGB), eliminating the need for palettes.
  • Framebuffer: Linear framebuffer for direct pixel manipulation.
    • Double Buffering: Default method (parameter -l 1 is default).
    • Triple Buffering: Optional (-l 2 or more) for higher fps.
  • Rendering: Direct pixel manipulation by the CPU in the framebuffer. Frame is rendered onto the screen using OpenGL as a texture.
  • Command-Line Interface: dotnet mode13hx.dll [command] [options]
  • Input Handling: Simplified input via OpenTK for keyboard and mouse support.
  • Performance: Supports high frame rates: 60, 120, 144 FPS with V-Sync; uncapped without V-Sync.

Repository: mode-13hx

Top comments (0)