Nerd For Tech
Published in

Nerd For Tech

Back to the 90s with C

Remember those retro-games from the 80s and 90s!

Source: https://blog.archive.org/2019/10/13/2500-more-ms-dos-games-playable-at-the-archive/, https://www.lifewire.com/best-ms-dos-games-4058702, https://boingboing.net/2021/08/27/find-out-about-new-dos-games-at-dos-haven.html

These DOS games would make some of you really nostalgic. Good old days with consoles and all. Today, I would introduce you to an amazing C library written by Mattias Gustavsson which lets you create these amazing retro style games.

“dos-like is a programming library/framework, kind of like a tiny game engine, for writing games and programs with a similar feel to MS-DOS productions from the early 90s. But rather than writing code that would run on a real DOS machine, dos-like is about making programs which runs on modern platforms like Windows, Mac and Linux, but which attempts to recreate the look, feel, and sound of old DOS programs.”

These are some example snippets from the site that you can create:

Source: https://github.com/mattiasgustavsson/dos-like

Now, let’s start exploring the library. It is, in fact, very easy to install. First clone this GitHub repo: https://github.com/mattiasgustavsson/dos-like

The directory structure should be like this:

The compiler is located inside the tcc folder.

The ‘tcc.exe’ is the most important file. (I am covering Windows installation only) You should add it to the path which should be like path/tcc

Here path is the location where the repository was cloned. If the tcc path is correctly set, you can go to the command prompt and type tcc. You should see something like this:

This means that the library is correctly installed

Now let’s see a few example programs. Some examples are already included by the author here: https://github.com/mattiasgustavsson/dos-like/tree/main/source

Based on the mandelbrot example, I wrote the program for the Burning ship fractal:

// Burning Ship fractal inspired by Port of mandelbrot tutorial code by Lode Vandevenne 
// https://lodev.org/cgtutor/juliamandelbrot.html#Mandelbrot_Set_
#include <math.h>
#include <stdlib.h>
#include "dos.h"
int main(int argc, char *argv[])
{
setvideomode( videomode_320x200 );
setdoublebuffer(1);
for( int i = 0; i < 32; ++i ) setpal( i, 0, 0, 31 - i );
int w = 320;
int h = 200;
//each iteration, it calculates: newz = oldz*oldz + p, where p is the current pixel, and oldz stars at the origin
double pr, pi; //real and imaginary part of the pixel p
double newRe, newIm, oldRe, oldIm; //real and imaginary parts of new and old z
double zoom = 1, moveX = -0.5, moveY = 0; //you can change these to zoom and change position
int maxIterations = 255;//after how much iterations the function should stop
double zoomSpd = 0.005f;
for( ; ; ) {
//loop through every pixel
for(int y = 0; y < h; y++)
for(int x = 0; x < w; x++)
{
//calculate the initial real and imaginary part of z, based on the pixel location and zoom and position values
pr = 1.5 * (x - w / 2) / (0.5 * zoom * w) + moveX;
pi = (y - h / 2) / (0.5 * zoom * h) + moveY;
newRe = newIm = oldRe = oldIm = 0; //these should start at 0,0
//"i" will represent the number of iterations
int i;
//start the iteration process
for(i = 0; i < maxIterations; i++)
{
//remember value of previous iteration
if (newRe < 0)
{
oldRe = -newRe;
}
else{
oldRe = newRe;
}
if (newIm < 0)
{
oldIm = -newIm;
}
else{
oldIm = newIm;
}
//the actual iteration, the real and imaginary part are calculated

newRe = oldRe * oldRe - oldIm * oldIm + pr;
newIm = 2 * oldRe * oldIm + pi;
//if the point is outside the circle with radius 2: stop
if((newRe * newRe + newIm * newIm) > 4) break;
}
//draw the pixel
putpixel(x, y, ( i + 32 ) & 255 );
if( keystate( KEY_ESCAPE ) || shuttingdown() ) exit(0);
}
swapbuffers();
zoom += zoomSpd;
moveX -= 0.0050109f / zoom;
zoomSpd *= 1.005;
}
return 0;
}

This produces results like:

Here is another sample program that does some simple graphics stuff. Here we follow the mouse pointer and draw circles.

#include <stdlib.h>
#include "dos.h"
#include <windows.h>
//author: Ujjayanta
int main(int argc, char **argv[]){

setvideomode(videomode_320x200);

int x, y;
POINT xypos;
GetCursorPos(&xypos);

while(!shuttingdown())
{
GetCursorPos(&xypos);
for(int i =0 ; i<5;i++){
x = xypos.x;
y = xypos.y;
setcolor(rand()%256);
circle(x%320,y%200,4);
}
for(int i =0 ; i<5;i++){
x = xypos.x;
y = xypos.y;
setcolor(rand()%256);
circle(0,0,4);
}

if( keystate( KEY_ESCAPE ) ) break;

}


return 0;
}

--

--

--

NFT is an Educational Media House. Our mission is to bring the invaluable knowledge and experiences of experts from all over the world to the novice. To know more about us, visit https://www.nerdfortech.org/.

Recommended from Medium

Code as religion

Code Teal: Making Computer Science Fun with Hockey

Why choose .NET for Enterprise application development in 2021–22

How does cypress change the game in Test automation?

Write Port Scanner In C

Redis Is Not Just a Cache — DZone Database

Creating a CloudFront using CLI

Generics In java

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Ujjayanta Bhaumik

Ujjayanta Bhaumik

MSc Computer Vision, Graphics and Imaging, University College London

More from Medium

The differences between static and dynamic libraries

Lost Server Access — Postmortem

Why you no?! — Iterative Refactoring

How to Fix SEC_ERROR_UNKNOWN_ISSUER in Firefox?