	Phobos's Turbo Pascal Demo Coding Tutors for Beginners
                        [C++ Update by Karma]
             Tutorial 3 - The VGA screen, pixels and lines.

20th Dec '96
                           
     Hi, this is a conversion of Phobos Pascal tutes to C++.
     I've converted all of his pascal code into C++ but I have left
     the original text unaltered.  So I take *no* credit for this
     tutorial, so you still have to mail questions to phobos ;-)
     Anyway the code was written and tested in Borland C++ 3.1
     Any comments by me will be in [ ].

     BTW: I didn't convert tutes 1 & 2 because they concentrated on
     pascal and I couldn't see the point of writing a C++ version as
     people don't wanna know about that stuff, they wanna know about
     graphics!  But if you bug me enough perhaps I might.
     so lets get on with it!   -Karma (cc6pwa@isis.sunderland.ac.uk)

Introduction
=============

Right, I'd bet you never thought I'd ever get round to it, but this tutor is 
going to concentrate on some graphics!!!  I'll be using Denthor's GFX3 tpu.  
Some people may feel that this is wrong and I should write my own graphics 
functions, but quite frankly, as I don't know asm, I can't.  Besides, 
Denthor's is great already!  Also, these tutors are about how to create demo 
effects, not how the tools (Denthor's tpu) work.

[for C++ we will be using gfx.cpp which I converted from GFX3.PAS]

Crank it up to MCGA 256 colours!
---------------------------------

Okay I expect everyone knows what VGA is from games.  It's a 320x200 screen
that allows you to use 256 colours.  MCGA is, for our purposes, the same as
VGA.  Okay we'll need to call a procedure from Denthor's tpu to get in MCGA,
so here goes :

----------------------------------------------------------------------
[Pascal]

USES crt,gfx3;       {Notice we have to call gfx3 here as it's a unit}

BEGIN
  setmcga;  	     {This is all we need to do to get into MCGA!}
  settext;	     {settext is kinda the oppersite to setmcga, it puts us}
END;							{back in text mode}

[C++]

#include "gfx.cpp"

void main() {
  setmcga();  // Whoa! mcga mode!
  settext();  // back to textmode :(
 }
--------------------------------------------------------------------------

BTW - I don't think I've told you about comments.  When you write a program,
you may want to (and it's good practise) put comments in to remind yourself,
or inform other people what the code does.  Comments go in curly brackets like
above.   {the comment}
[ // no comment ;-) ]

Okay, what the above code does is change the graphics mode to MCGA, and then
back to text mode.  That's not very interesting on it's own though is it?

Some graphics!
---------------

Okay as I explained before, the screen is 320 pixels wide, and 200 pixels
deep.  But unlike on a graph, co-ordinate 0,0 is in the top left hand corner.
Also, because the screen starts at 0,0 it is 0 to 199 down and 0 to 319
across.  This is still the full 320x200.
Here's a graphical representation:

		      -------------------------------
		      0,0                       319,0
		                                     
		                  160,100            
		                     .               
		                                     
		                                     
		                                     
		      0,199                   319,199
		      -------------------------------

So if we wanted to put a pixel in the centre of the screen, this how we'd do
it.

---------------------------------------------------------
[Pascal]

USES crt,gfx3;

BEGIN
  setmcga;
  putpixel (160,100,15,vga);
  READKEY;
  settext;
END;

[C++]

#include <conio.h>
#include "gfx.cpp"

void main() {
  setmcga();
  putpixel(160,100,15,vga);
  getch();
  settext();
 }
------------------------------------------------------------
	      putpixel (160, 100, 15, vga);
			/    /    \    \
		       /    /      \    \
		      /    /        \    \This says where to put the pixel
	  The x coord/    /          \     For now just put vga
			 /            \
	     The y coord/              \The colour - 15 happens to be white

Okay, so now you can put a pixel anywhere on the screen by changing the x and
y co-ordinates in any colour (0 to 255).

It would be very long winded to have to tell the computer where to put the
pixel all the time, so we can use loops to cut down on code.  So to colour the
whole screen blue (colour 1) we'd do this :

---------------------------------------------------------
[Pascal]

USES crt,gfx3;

VAR x, y : INTEGER;

BEGIN
  setmcga;
  FOR x := 0 TO 319 DO BEGIN
    FOR y := 0 TO 199 DO BEGIN
      putpixel (x,y,1,vga);
    END;
  END;
  READKEY;
  settext;
END;

[C++]

#include <conio.h>
#include "gfx.cpp"

int x, y;

void main() {
  setmcga();
   for(x=0;x<319;x++) {
    for(y=0;y<199;y++) {
     putpixel(x,y,1,vga);
      }
    }
    getch();
   settext();
  }
------------------------------------------------------------
What this loop (or loop within a loop ;-) ) will do will fill the screen with
white dots.  We do 0 to 319 x 0 to 199 do get our full 64000 pixels.  64000 is
obviously how many pixels there are on the screen.

Well that's all very nice, but a blue screen isn't the most advanced demo
effect you've ever seen is it?  Lets change the colours too, huh?

---------------------------------------------------------
[Pascal]

USES crt,gfx3;

VAR x, y, colour : INTEGER;

BEGIN
  setmcga;
  colour := 0;                    {Set the our colour to 0 (black)}
  FOR x := 0 TO 319 DO BEGIN
    FOR y := 0 TO 199 DO BEGIN
      IF colour < 256 THEN INC (colour);    -------
      putpixel (x,y,colour,vga);                   
      IF colour = 255 THEN colour := 0;     -------
    END;                                           
  END;                                             
  READKEY;                                         
  settext;	                                   
END;		                                   
------------------------------------------------------------
Let me explain these two lines of code.  We don't want the colour to go over
255, the maximum colour.  So before we increase the colour each time, we
check to make sure it isn't greater than 255.  That's what the < sign means,
it's the same as in math, less than.  And > is greater than, <= is less or
equal to, >= is greater or equal to, = is equal to, and finally, <> is not
equal to.  So....

[Pascal]
Symbol 		Meaning
-------         --------
>		Greater than
<		Less than
>=		Greater than or equal to
<=		Less than or equal to
=		Equal to
<>		Not equal to

[C++]
Symbol 		Meaning
-------         --------
>		Greater than
<		Less than
>=		Greater than or equal to
<=		Less than or equal to
==              Equal to
!=              Not equal to

Anyway, where was I?  Oh yes.  So is the colour IS equal to 255, we reset it
back to 0, so it can go on all over again.

[C++]

#include <conio.h>
#include "gfx.cpp"

int x, y, colour;

void main() {
  setmcga();
  colour=0;              // Set the our colour to 0 (black)
  for(x=0;x<319;x++) {
   for(y=0;y<199;y++) {
    if(colour<256) colour++;
     putpixel(x,y,colour,vga);
      if(colour==255) colour=0;
       }
     }
     getch();
    settext();
  }

Hmm.. That's quite pretty, but I think we can add a little to it.  How
about..A bit or randomness!!

Random Numbers
-----------------

Random numbers are easy got hold of in Pascal, and this is how we do it.

---------------------------------------------------------
[Pascal]

USES crt,gfx3;

VAR x, y, colour : INTEGER;

BEGIN
  RANDOMIZE;
  setmcga;
  FOR x := 0 TO 319 DO BEGIN
    FOR y := 0 TO 199 DO BEGIN
      putpixel (x,y,RANDOM(255),vga);
    END;
  END;
  READKEY;
END;

[C++]

#include <conio.h>
#include "gfx.cpp"

int x, y, colour;

void main() {
  setmcga();
  for(x=0;x<319;x++) {
   for(y=0;y<199;y++) {
    putpixel(x,y,rand() % 256,vga);
     }             // A random number between 0 and 255
    }
     getch();
  }
------------------------------------------------------------

RANDOMIZE
------------
You only ever have to call this once in your programs.  It sets up the random
function ready for use later on.  You'll find if you don't call it, when you
use RANDOM, the number you get will always be the same.

RANDOM(255)
------------
This will randomly generate a number between 0 and 255.
[In C++ use rand() % 256, the random(255) in C++ is way too slow! and you
 have to call randomize() which resides in stdlib.h ]

Hey that's quite pretty!

Okay, lets take a look at some lines.

Lines!
-------

Along with pixels and circles, lines are one of the most important drawing
tools.  Here's how we draw a line.

------------------------------------------------
[Pascal]

USES crt,gfx3;

BEGIN
  setmcga;
  line (0,0,319,199,15,vga);
  READKEY;
  settext;
END;

[C++]

#include <conio.h>
#include "gfx.cpp"

void main() {
  setmcga();
  line(0,0,319,199,15,vga);
  getch();
  settext();
 }
--------------------------------------------------------
		    line (0, 0, 319, 199, 15, vga);
			 /   /   \    \    \    \
		       /    /     \     \   \As with putpixel
		     /     /       \      \
 x coord of point a/      /         \       \x coord of point b
			 /           \
      y coord of point a/             \y coord of point b

Okay, that's pretty simple, lets do something a bit pretty with that.  How
about drawing lines all over the screen at random points, random lengths, and
random colours...

Take a look at this...

---------------------------------------------------------
[Pascal]

{$X+}
USES crt,gfx3;

BEGIN
  RANDOMIZE;
  setmcga;
  REPEAT
    line (RANDOM(319), RANDOM(199), RANDOM(319), RANDOM(199), RANDOM(255),
      vga);
  UNTIL keypressed;
  settext;
END;

[C++]

#include <conio.h>
#include "gfx.cpp"

void main() {
  setmcga();
   do {
      line(rand()%320,rand()%200,rand()%320,rand()%200,rand()%256,vga);
      } while (!kbhit());
   settext();
  }
------------------------------------------------------------
Okay there are a few new things here.  The repeat statement doesn't stop when
a value is satisfied as in the last tutor, it ends when someone presses a key
(keypressed).  We must add the compiler directive {$X+} at the start of our
code though to make keypressed work on it's own.
[ In C++ we use a do/while, kbhit() is just like keypressed ]

Okay that's it!  Remember to take a look at the code in the .pas file.
[ and in the .cpp file ;-) ]

Things to do
-------------
Draw some pretty patterns using the putpixel and line procedures.  Try and be
as creative as possible.  If you make something, why not send it to me?  I'd
love to see some of your work!

Next week I'll be taking a look at how to change the colour palette, as you
must admit, the basic 256 that are standard are a bit limited yes?  Also some
other stuff I haven't thought of yet.

Contact as usual is :

Email :  ci.phobos@dial.pipex.com

Seeya soon!  The next tutor won't be out until after Christmas (Dec 27th) so..

			- MERRY CHISTMAS !!! -
