943,703 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 15585
  • C++ RSS
You are currently viewing page 1 of this multi-page discussion thread
Jul 26th, 2004
0

Graphics in Pixel,Mode13h:Part 1

Expand Post »
C++ Syntax (Toggle Plain Text)
  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

C++ Syntax (Toggle Plain Text)
  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):
Quote ...
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

C++ Syntax (Toggle Plain Text)
  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:

C++ Syntax (Toggle Plain Text)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dos.h>
  4. #include <mem.h>

Borland (Should work on most compilers)

C++ Syntax (Toggle Plain Text)
  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:

C++ Syntax (Toggle Plain Text)
  1. set_mode(MODE_13H); //to get into mode13h
  2. set_mode(TEXT_MODE); //to get back into the normal mode

DJGPP

C++ Syntax (Toggle Plain Text)
  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.

C++ Syntax (Toggle Plain Text)
  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.

C++ Syntax (Toggle Plain Text)
  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
Reputation Points: 108
Solved Threads: 7
Posting Whiz in Training
FireNet is offline Offline
256 posts
since May 2004
Jul 26th, 2004
0

Re: Graphics in Pixel,Mode13h:Part 1

C++ Syntax (Toggle Plain Text)
  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. }
Reputation Points: 108
Solved Threads: 7
Posting Whiz in Training
FireNet is offline Offline
256 posts
since May 2004
Aug 23rd, 2004
0

Re: Graphics in Pixel,Mode13h:Part 1

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
Reputation Points: 10
Solved Threads: 0
Newbie Poster
marvis4life is offline Offline
5 posts
since Jul 2004
Aug 25th, 2004
0

Re: Graphics in Pixel,Mode13h:Part 1

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
Reputation Points: 108
Solved Threads: 7
Posting Whiz in Training
FireNet is offline Offline
256 posts
since May 2004
Dec 13th, 2004
0

Re: Graphics in Pixel,Mode13h:Part 1

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
Reputation Points: 16
Solved Threads: 6
Posting Pro in Training
1o0oBhP is offline Offline
445 posts
since Dec 2004
Feb 5th, 2005
0

Re: Graphics in Pixel,Mode13h:Part 1

C++ Syntax (Toggle Plain Text)
  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
Reputation Points: 10
Solved Threads: 0
Light Poster
odee is offline Offline
27 posts
since Dec 2004
Feb 6th, 2005
0

Re: Graphics in Pixel,Mode13h:Part 1

the code:
C++ Syntax (Toggle Plain Text)
  1. unsigned char *VGA = (unsigned char *)0xA0000000L;

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

why? what's with far?
Reputation Points: 10
Solved Threads: 0
Light Poster
odee is offline Offline
27 posts
since Dec 2004
Feb 6th, 2005
0

Re: Graphics in Pixel,Mode13h:Part 1

mode 13 hex ONLY works under DOS in 16 bit mode. It cannot be entered in Windows in any mode.
Team Colleague
Reputation Points: 1658
Solved Threads: 331
duckman
jwenting is offline Offline
7,719 posts
since Nov 2004
Feb 7th, 2005
0

Re: Graphics in Pixel,Mode13h:Part 1

Quote ...
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
Reputation Points: 16
Solved Threads: 6
Posting Pro in Training
1o0oBhP is offline Offline
445 posts
since Dec 2004
Feb 7th, 2005
0

Re: Graphics in Pixel,Mode13h:Part 1

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.
Reputation Points: 16
Solved Threads: 6
Posting Pro in Training
1o0oBhP is offline Offline
445 posts
since Dec 2004

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: calculator help
Next Thread in C++ Forum Timeline: adding to a string





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC