Graphics in Pixel,Mode13h:Part 1

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: May 2004
Posts: 256
Reputation: FireNet will become famous soon enough FireNet will become famous soon enough 
Solved Threads: 6
FireNet's Avatar
FireNet FireNet is offline Offline
Posting Whiz in Training

Graphics in Pixel,Mode13h:Part 1

 
0
  #1
Jul 26th, 2004
  1.  
  2. Mode13h
  3. The Beginning of 3D/2D Graphics


Intro


Lots of people want to know how to do graphics but find most APIs like
OpenGL, DirectX etc too complex for a beginner, especially as they involve GUI code which follows a different approach from the simple dos programming Here, I will present a simple graphics mode, which can be easily used via dos console programming

What I will be covering

  1. Part 1:Introduction to Mode13h (this part)
  2. Part 2:Blazing:Lets speed up and burn (algorithms,double buffering)
  3. Part 3:Dangers and Protection Systems (wait and see)
  4. Part 4:Bitmap Loading and Animation (woooooo!!!!)
  5. Part 5:Assembler,Let's go faster (world of supersonics,C++ code)
  6. Part 6:Palette fun (let the artist live)
  7. Part 7:Intro to 3D (::::::::::::::::)
  8. Part 8:3D Star Fields (weee!!!!)
  9. Part 9:Wrapup (end,alternate techs)
  10.  

Ok, this series will take sometime or so. Maybe weekly updates. We go
slow in this article. Part 2 will be larger and contain code.

History of Mode13h

Here's a quote by a 3D programmer, Jacco Bikker (The Phantom):
In the old days, there was DOS. And in DOS, there was mode 13. Once
initialized, the unsuspecting coder could write to video memory, starting
at a fixed address, A0000 if I am correct. All this didn't block the computer, and worked on virtually every VGA card in the world. The mode allowed for output of 256 color graphics, and that was just fine, if you did it well.

But then something really bad happened. SVGA cards started to appear
everywhere, and to make things worse, computers became fast enough
to do true-color graphics. From that moment on, nothing was certain
anymore. You had 15 bit graphics (for some VERY odd reason someone
decided to ignore a whole bit), 16 bit graphics, 24 bit, 32 bit, and random
orderings of the color components in these arrays of bits. You could for
instance encounter a card that did RGB, but also BGR, or RGBA... So the
VESA standard was invented. This made things bearable again.
So, anyway Mode13h is a graphics mode from the past, with a low resolution so don't compare it with the latest stuff you see in the games. People do say Mode13h is dead, it's not true, even though no game company makes games in Mode13h anymore, it will serve as nice intro beginners, as it has done before. And btw, lots of games are still being made in mode13h by hobbyists.

Let the coding begin.....

Tools of the Trade

Mode13h does not work in the standard console mode, so you will have to change a few settings on you compiler. You will have to use DOS, Large memory model. Don't worry too much. Just getting into mode13h or getting out of it is different on different compilers the rest is quite the same. The simplicity comes from the fact that you can write to the screen pixels as if you were writing into a char array. It simple to set up x, y coordinate system in Mode13h.

You can get TurboC for Borland's site for free. It is quite good if you want an easy way to compile you programs. Remember to compile in the LARGE memory model!

To compile in Borland C: bcc -ml yourprogram.c I would still recommend that you get a C++ compiler to compile your programs as I will use stuff like classes later on. And it's much easy to code if you can use the advanced features which C++ offers over C.

Compilers

  1. Borland C++ (My fav)
  2. DJGPP (Free,Very Good,Protected mode programs)
  3. Dev-C++ (Dont know,heard somewhere it can do Mode13h)

Headers

Keep all functions you get in a header files. That way you won't have to modify all you programs to change something. Standard Headers to include:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dos.h>
  4. #include <mem.h>

Borland (Should work on most compilers)

  1. #define VIDEO_INT 0x10 /* the BIOS video interrupt. */
  2. #define SET_MODE 0x00 /* BIOS func to set the video mode. */
  3. #define MODE_13H 0x13 /* use to set 256-color mode. */
  4. #define TEXT_MODE 0x03 /* use to set 80x25 text mode. */
  5.  
  6. #define SCREEN_WIDTH 320 /* width in pixels of mode 0x13 */
  7. #define SCREEN_HEIGHT 200 /* height in pixels of mode 0x13 */
  8.  
  9. #define SCREEN_SIZE SCREEN_WIDTH*SCREEN_HEIGHT
  10.  
  11. #define NUM_COLORS 256 /* number of colors in mode 0x13 */
  12.  
  13. byte *VGA=(byte *)0xA0000000L; /* this points to video memory. */
  14.  
  15. void set_mode(byte mode)
  16. {
  17. union REGS regs;
  18.  
  19. regs.h.ah = SET_MODE;
  20. regs.h.al = mode;
  21. int86(VIDEO_INT, &regs, &regs);
  22. }

Use it as:

  1. set_mode(MODE_13H); //to get into mode13h
  2. set_mode(TEXT_MODE); //to get back into the normal mode

DJGPP

  1. void set_mode(byte mode)
  2. {
  3. union REGS regs;
  4.  
  5. regs.x.ax = mode;
  6. int86(VIDEO_INT, &regs, &regs);
  7. }

Properties of Mode13h

It's 320 pixels wide and 200 pixels high. There are 256 colors available, and their values fit in 1 byte, i.e. the size of a char. I mentioned earlier that putting a pixel was as simple as putting a char in an array. The VGA memory is 64000 (320 * 200) bytes in size. Location(0,0) is at the top left hand corner of the screen. So Mode13h is simple to implement and it is fast.

Drawing In Mode13h

Ah the section you been all waiting for. Here we will just discuss putting a pixel and clearing the screen. Later on I will talk about algorithms for drawing lines, circles, boxes etc. They all require you to be able to put a pixel any way.

  1. void pixel(int x,int y,byte color) //Puts a pixel by writing directly to memory
  2. {
  3. VGA[y*SCREEN_WIDTH+x]=color;
  4. }
  5.  
  6. void clear(int color)
  7. {
  8. memset(VGA,color,SCREEN_SIZE);
  9. }

Really simple,eh? Look at the function for putting a pixel to the screen. We are simply writing to the VGA memory as if it was just a char array.

Go ahead, try something,anything!You should be able to draw straight lines with simple functions.

  1. void line_horz(int x,int y,int len,byte color) //Draw horizontal lines
  2. {
  3. for(int i=0;i<len;i++)
  4. {
  5. pixel(x+i,y,color)
  6. }
  7. }

Stuff for You to do
  1. Of course, make a function to draw vertical lines.
  2. funtion(s) to draw square,rectancles.
  3. Do benchmark tests.(findout how fast the system is)

Ending Notes

Next edition, we will talk about double buffering and speeding up our drawing. Yea, blazing fast. Also you will get a few algorithms (line, circle) and some good stuff.

Have fun.
Last edited by happygeek; Nov 12th, 2006 at 11:53 am. Reason: Formatting
See what you can, remember what you need

Fourzon | Earn via Coding
Reply With Quote Quick reply to this message  
Join Date: May 2004
Posts: 256
Reputation: FireNet will become famous soon enough FireNet will become famous soon enough 
Solved Threads: 6
FireNet's Avatar
FireNet FireNet is offline Offline
Posting Whiz in Training

Re: Graphics in Pixel,Mode13h:Part 1

 
0
  #2
Jul 26th, 2004
  1. /*
  2. A Little help with the benchmarking.(C++)
  3. benchmark.h
  4.  
  5. Notes:
  6. None too perfect,not even tested.This was just to give you an
  7. idea as to how you could go about making a benchmarking system
  8. Btw,It should work :).
  9.  
  10. The class need not be used,only important and tested thing is the
  11. GetTickCountM13();Use it to make your own system.We will need this
  12. from part II.
  13. */
  14.  
  15. word *clock=(word *)0x0000046C;
  16.  
  17. double GetTickCoutM13()
  18. {
  19. return (double)*clock;
  20. }
  21.  
  22. Class Benchmark_system
  23. {
  24. private:
  25. ofstream log;
  26. double tick;
  27.  
  28. public:
  29. Benchmark_system();
  30. ~Benchmark_system();
  31. void init(char*);
  32. void start();
  33. void end();
  34. };
  35.  
  36. Benchmark_system::Benchmark_system()
  37. {
  38. tick = 0;
  39. }
  40.  
  41. Benchmark_system::~Benchmark_system()
  42. {
  43. log.close();
  44. }
  45.  
  46. void Benchmark_system::init(char* file)
  47. {
  48. log.open(file,ios::trunc);
  49. log<<"\nBenchmarking System 0.1, by Firenet\nhttp://xlock.hostcubix.com\n\n";
  50. }
  51.  
  52. void start()
  53. {
  54. tick = GetTickCoutM13();
  55. }
  56.  
  57. void end()
  58. {
  59. log<<"\nTicks taken: "<<(tick-GetTickCoutM13());
  60. }
See what you can, remember what you need

Fourzon | Earn via Coding
Reply With Quote Quick reply to this message  
Join Date: Jul 2004
Posts: 5
Reputation: marvis4life is an unknown quantity at this point 
Solved Threads: 0
marvis4life's Avatar
marvis4life marvis4life is offline Offline
Newbie Poster

Re: Graphics in Pixel,Mode13h:Part 1

 
0
  #3
Aug 23rd, 2004
Firenet,
thanks for this post, i really have learnt from it, but please can u make it a little easier for beginners like me to catch with little ease?
thanks for ur cooperation and please send the other parts.
marvis
Living in an atmosphere of dominion....:)
Reply With Quote Quick reply to this message  
Join Date: May 2004
Posts: 256
Reputation: FireNet will become famous soon enough FireNet will become famous soon enough 
Solved Threads: 6
FireNet's Avatar
FireNet FireNet is offline Offline
Posting Whiz in Training

Re: Graphics in Pixel,Mode13h:Part 1

 
0
  #4
Aug 25th, 2004
Well,I have done the second part but still doing the code examples.About making it easier,I dont really know,but just simply follow the stuff like the bios calls,like you followed cout<<.Later when you progress you will learn about them.No use confusing yourself now.

Then again maybe I might do a section covering bios calls and stuff very lightly and drop that assembler section.

Hey I am not a know it all,but learned it from here and there, and still learning.

(P.S:I forgot a small bit in the code, the byte datatype is an unsigned char)
(just add a typedef unsigned char byte
See what you can, remember what you need

Fourzon | Earn via Coding
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 445
Reputation: 1o0oBhP is an unknown quantity at this point 
Solved Threads: 6
1o0oBhP's Avatar
1o0oBhP 1o0oBhP is offline Offline
Posting Pro in Training

Re: Graphics in Pixel,Mode13h:Part 1

 
0
  #5
Dec 13th, 2004
Dev-C++ wont do 13h without serious effort. I tried making it work for 2 years and found out something simple but fatally flawed and everyone MUST check this before doing mode 13h.

! COMPILE IN 16 BIT ! --> Dev-c++ is 32 bit and so requires MASSIVE amounts of asm before you can do anything in 13h and requires a bit of VBE code to get it working, if you have DJGPP however it can compile in 16 bit and so the code works fine. CHECK YOUR COMPLILERS i found out the hard way after a LONG time and a LOT of hard coding
http://sales.carina-e.com

no www
no nonsense

coming soon to a pc near you! :cool:
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 27
Reputation: odee is an unknown quantity at this point 
Solved Threads: 0
odee odee is offline Offline
Light Poster

Re: Graphics in Pixel,Mode13h:Part 1

 
0
  #6
Feb 5th, 2005
  1. typedef unsigned char bye;
  2.  
  3. byte *VGA=(byte *)0xA0000000L; /* this points to video memory. */

it has an error saying: Illegal initializatioin

i'm using turbo c++ v1.01
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 27
Reputation: odee is an unknown quantity at this point 
Solved Threads: 0
odee odee is offline Offline
Light Poster

Re: Graphics in Pixel,Mode13h:Part 1

 
0
  #7
Feb 6th, 2005
the code:
  1. unsigned char *VGA = (unsigned char *)0xA0000000L;

doesn't work for me, but this one does...
  1. unsigned char far *VGA = (unsigned char far *)0xA0000000L;

why? what's with far?
Reply With Quote Quick reply to this message  
Join Date: Nov 2004
Posts: 6,144
Reputation: jwenting is just really nice jwenting is just really nice jwenting is just really nice jwenting is just really nice 
Solved Threads: 212
Team Colleague
jwenting's Avatar
jwenting jwenting is offline Offline
duckman

Re: Graphics in Pixel,Mode13h:Part 1

 
0
  #8
Feb 6th, 2005
mode 13 hex ONLY works under DOS in 16 bit mode. It cannot be entered in Windows in any mode.
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 445
Reputation: 1o0oBhP is an unknown quantity at this point 
Solved Threads: 6
1o0oBhP's Avatar
1o0oBhP 1o0oBhP is offline Offline
Posting Pro in Training

Re: Graphics in Pixel,Mode13h:Part 1

 
0
  #9
Feb 7th, 2005
unsigned char far *VGA = (unsigned char far *)0xA0000000L;
UNLESS you are compiling in 16 bit you CANNOT initialise a pointer to base VGA. Base VGA also is NOT 0xA000 in VBE systems (for 32bit ) as it varies and you need to get a pointer to it using asm statements. DJGPP is a classic one to use for 16 bit applications and you could use the pointer method, OR make use of the DOS functions which are MUCH better
http://sales.carina-e.com

no www
no nonsense

coming soon to a pc near you! :cool:
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 445
Reputation: 1o0oBhP is an unknown quantity at this point 
Solved Threads: 6
1o0oBhP's Avatar
1o0oBhP 1o0oBhP is offline Offline
Posting Pro in Training

Re: Graphics in Pixel,Mode13h:Part 1

 
0
  #10
Feb 7th, 2005
FireNet a good way to benchmark using the tutorial you just wrote would be to time a complete screen fill of pixels followed by some lines. Make it complex enough to differentiate between computer speeds.
http://sales.carina-e.com

no www
no nonsense

coming soon to a pc near you! :cool:
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the C++ Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC