# Drawing a single pixel (without X)



## purkkimestari (Jun 24, 2013)

How do I make a C program draw a single pixel on the screen (without using X or any other such thing)?

I would like to have the simplest, most rudimentary BIOS call for drawing pixels in VESA mode, in the form of a simple C program. All I have is a fresh install of FreeBSD in console mode, a minimal installation, and I want to keep things simple. Can I do simple VESA mode graphics without installing any new (or at least as few as possible) packages? 

My story:

I decided I wanted to learn to really use a computer. I decided to get learn to use some UNIX system, and really learn things by reading the source files for things I use. I installed FreeBSD, and started reading the handbook and setting up my computer for everyday use, looking for basic utils. I `pkg_add`'d X.Org and I almost fainted as I saw the flood of dependencies! I can't read the source files of all these hundreds of libraries! Anyway, so I decided to wipe the disk and reinstall FreeBSD, this time making sure I would only install packages with a humanly understandable number of dependencies. Now I want to do some graphics programming, as in draw pixels in C. The end.


----------



## fonz (Jun 24, 2013)

If anyone knows of a good VESA/VGA/syscons tutorial I'd be interested in that too. In the meantime, perhaps you can have a look at some of the syscons screensavers (/usr/src/sys/dev/syscons) and try to figure out how they work.


----------



## throAU (Jun 25, 2013)

I'd be keen too.

My interest in coding has waned significantly from my DOS days of being able to put a pixel on the screen in about 5 lines of code.


```
mv ax,0x13
int 10h
mv es,0x04000
mv di,10
mv es:di,255
```

(Maybe the segmentffset notation is a bit wrong, it's been a few years )

Trying to learn X or someone else's massive graphic library to just put a simple dot on the screen has got knobs on it as far as toying with graphics goes.


----------



## expl (Jun 25, 2013)

Probably want to start with graphics/svgalib. 0 dependencies and portable API.


----------



## Zare (Jun 25, 2013)

You don't need any ports to use rudimentary graphics. vgl(3)() and /usr/share/examples/libvgl directory should be enough to get you going.


----------



## fonz (Jun 25, 2013)

expl said:
			
		

> Probably want to start with graphics/svgalib.


Good shout. The OP _might_ want something more low-level [edit: which would be @Zare's sugestion], but for satisfying my personal curiosity this will probably do nicely.


----------



## _martin (Jun 25, 2013)

throAU said:
			
		

> ```
> mv ax,0x13
> int 10h
> mv es,0x04000
> ...


Aargh, good old DOS times  Not sure, but I think ES register can't be accessed directly. Maybe something like this:


```
mov ax, 0x13
int 0x10
mov ax, 0x0a000 ; vga segment
mov es, ax 
mov di, 0 ; location of pixel in 320x200 mode
mov al, 3  ; color to draw
stosb
```
I never used assembler in FreeBSD though


----------



## throAU (Jun 26, 2013)

Yup, I do believe you're right  

It's been about 20 years since I've touched any x86 assembly so I am likely quite rusty.  

I guess the point is:  being able to get a reward (pixel on the screen) within 5-6 lines of code enables new programmers interested in graphics to get started and actually see something for their efforts a lot more quickly than now, where you need to spend time learning an IDE, a graphics API, a windowing toolkit, etc.


edit:
Just had a peek at libvgl.

Neat.  Never even knew it existed.  This is exactly what I'm keen to play with - low level and simple enough to learn in about five minutes


----------



## expl (Jun 26, 2013)

throAU said:
			
		

> Just had a peek at libvgl.
> 
> Neat.  Never even knew it existed.  This is exactly what I'm keen to play with - low level and simple enough to learn in about 5 minutes



It is not really low level, quite the opposite. If you want to go with low level you might want to look into source code of the library itself, how it 'talks' to the hardware. Also if you want your code to be portable outside BSD I'd suggest using SVGAlib they are both implemented very similarly.


----------



## fonz (Jun 26, 2013)

To whom it may concern: I've done some mucking about with the libvgl example in /usr/share/examples/libvgl. There are a few things that caught my attention:

The demo obviously only works on the console and must either be run as root or be suid-root. However, neither libvgl itself nor the demo do any error checking. I therefore recommend that one starts by verifying that one is running with root privileges and is running on the console before doing anything. Otherwise, bus errors can occur at any time.
When I try to run the demo in a VESA screen mode (set using vidcontrol(1)), the demo itself works, but when the program ends and goes back to text mode the entire system freezes and all I can do is hit the Windows reset button. When I go back to the default mode first by doing `vidcontrol 80x25`, it does work. Does anyone know how to check for this, or better yet: how to prevent the system freeze?

I haven't tried svgalib yet, but I will.


----------



## throAU (Jun 27, 2013)

expl said:
			
		

> It is not really low level, quite the opposite. If you want to go with low level you might want to look into source code of the library itself, how it 'talks' to the hardware. Also if you want your code to be portable outside BSD I'd suggest using SVGAlib they are both implemented very similarly.



Maybe I used "low level" in a confusing context. I didn't low level in so far as it's close to the hardware.  Just - primitive.  Simple to use. I.e., no advanced window management and the baggage that goes with it - no need to open an OpenGL context, etc.

From looking at libvgl, yes, sure it is not portable, but in terms of experimenting quickly with drawing algorithms there's a lot less glue code to write. Simply set _the_ video mode _and_ start drawing pixels (i.e., like you could in good old DOS via a BIOS interrupt and poking at bytes in memory directly).

The cross platform and portable nature of SVGAlib means there are a lot more hoops you need to jump through (determine pixel depth/screen size, set up a drawing canvas, etc.) - which is fine if you are writing something to be portable, but if you're just wanting to play with some graphical effects, it's an initial barrier to entry (i.e., I don't want to spend time learning a graphics library, just let me set a screen up and put pixels to test ideas!).

I agree, SVGAlib is certainly the way to go for any real project though - but the general algorithm you play with in libvgl could easily be ported if required.

edit:
And yeah, figured it would be console only/root only.  For my purposes, this isn't an issue.


----------



## expl (Jun 27, 2013)

throAU said:
			
		

> The cross platform and portable nature of SVGAlib means there are a lot more hoops you need to jump through (determine pixel depth/screen size, set up a drawing canvas, etc.) - which is fine if you are writing something to be portable, but if you're just wanting to play with some graphical effects, it's an initial barrier to entry (i.e., I don't want to spend time learning a graphics library, just let me set a screen up and put pixels to test ideas!).



No, not really. It is very similar to libvgl at API level as well. You can draw your pixel just in as many lines and there is no need to check maximum color depth and screen resolution as you can safely assume that every console supports all SuperVGA modes as it is no longer 80s .


----------



## andyzammy (Jun 27, 2013)

I've been interested in this before (I was limited to Windows at the time), and the solution I came up with was SDL, which is also portable, but I guess it's much higher level than the console libs mentioned here (your SDL program would either get it's own "window", or you could make it full screen - at least, I never figured out how to get rid of the window box containing my hello world pixels...)


----------



## throAU (Jun 28, 2013)

expl said:
			
		

> No, not really. It is very similar to libvgl at API level as well. You can draw your pixel just in as many lines and there is no need to check maximum color depth and screen resolution as you can safely assume that every console supports all SuperVGA modes as it is no longer 80s .



Hmm, maybe _I_'m thinking of SDL...


----------

