[comp.lang.c] Fast screen drawing...

dank@skat.usc.edu (Dan King) (05/04/90)

I've been reading this group for a couple of weeks now, and haven't
seen this mentioned, so I feel fairly confident that it's not a
question that gets asked every two days.

I'm using Turbo C to write an application that does a lot of text
drawing (normal characters, not graphics or bitmapped) on platforms
ranging from XTs to '386s and have noticed that the printing speed
coming out of printf(), puts(), and putch() is dreadfully slow.  Has
anyone else noticed this?  Am I missing something?

Even just when puts()ing constant strings in a "tiny" memory model
(does this make a difference?), it's pretty slow.  I'd rather not
write inline code to do my own character writing but that looks like
what it comes down to.  Has anyone else solved this problem?

dank

jhallen@wpi.wpi.edu (Joseph H Allen) (05/04/90)

In article <24493@usc.edu> dank@skat.usc.edu (Dan King) writes:
>
>I've been reading this group for a couple of weeks now, and haven't
>seen this mentioned, so I feel fairly confident that it's not a
>question that gets asked every two days.
>
>I'm using Turbo C to write an application that does a lot of text
>drawing (normal characters, not graphics or bitmapped) on platforms
>ranging from XTs to '386s and have noticed that the printing speed
>coming out of printf(), puts(), and putch() is dreadfully slow.  Has
>anyone else noticed this?  Am I missing something?
>
>Even just when puts()ing constant strings in a "tiny" memory model
>(does this make a difference?), it's pretty slow.  I'd rather not
>write inline code to do my own character writing but that looks like
>what it comes down to.  Has anyone else solved this problem?

Yep, all of those functions are slow since they go through DOS.  You have
several options (listed in order of compatibility and reverse order of speed):

1)	Use the undocumented console output function.  All dos console output
	eventually goes through this anyway:

		void cputc(char a)
		{
		_AL=a;
		geninterrupt(0x29);
		}

2)	Use the BIOS functions:

		/* Set cursor position */

		void cpos(unsigned x,unsigned y)
		{
		_DH=y;
		_DL=x;
		_BH=0;
		_AH=2;
		geninterrupt(0x10);
		}

		/* Write character. */

		void cputc(char a)
		{
		_BX=7;
		_AH=0xe;
		_AL=a;
		geninterrupt(0x10);
		}

		/* Write characters without moving the cursor */
		/* The character is written count times.  This can be
		used to clear areas of the screen */

		void cwrite(char a,unsigned count)
		{
		_CX=count;
		_BX=7;
		_AH=10;
		_AL=a;
		geninterrupt(0x10);
		}

		/* Scroll up */
		/* Count is lines to scroll, (x1,y1) is upper left and
		(x2,y2) is lower right of region to scroll */

		void scrup(int x1,int y1,int x2,int y2,int count)
		{
		_DH=y2;
		_DL=x2;
		_CH=y1;
		_CL=x1;
		_BH=7;
		_AH=6;
		_AL=count;
		geninterrupt(0x10);
		}

		/* Scroll down */
		/* Count is lines to scroll, (x1,y1) is upper left and
		(x2,y2) is lower right of region to scroll */

		void scrup(int x1,int y1,int x2,int y2,int count)
		{
		_DH=y2;
		_DL=x2;
		_CH=y1;
		_CL=x1;
		_BH=7;
		_AH=7;
		_AL=count;
		geninterrupt(0x10);
		}

3) Write directly to the screen.  Don't do this if you're using snowy CGA

		unsigned far *screen;
		unsigned height;
		unsigned width;

		/* Get screen parameters */

		void sparms(void)
		{
		_AH=15;
		geninterrupt(0x10);
		width=_AH;
		if(_AL==7) screen=(unsigned far *)0xb0000000;
		else screen=(unsigned far *)0xb8000000;
		height=*(unsigned char far *)0x00400084;
		if(!height) height=25;
		}

		So then to write to the screen you just:

		#define swrite(a,x,y) (*(screen+x+y*width)=0x700+(a))

		And then use the BIOS function to position the cursor.

Oh and there's one other alternative:  Look up the turbo-C function: puttext()
It's also quite fast.
-- 
jhallen@wpi.wpi.edu (130.215.24.1)

scott@bbxsda.UUCP (Scott Amspoker) (05/05/90)

In article <12641@wpi.wpi.edu> jhallen@wpi.wpi.edu (Joseph H Allen) writes:
>In article <24493@usc.edu> dank@skat.usc.edu (Dan King) writes:
>>I'm using Turbo C to write an application that does a lot of text
>>drawing (normal characters, not graphics or bitmapped) on platforms
>>ranging from XTs to '386s and have noticed that the printing speed
>>coming out of printf(), puts(), and putch() is dreadfully slow.  Has
>>anyone else noticed this?  Am I missing something?
>
>Yep, all of those functions are slow since they go through DOS.  You have
>several options (listed in order of compatibility and reverse order of speed):
>
>[suggestions deleted]

Before you go off and do bios calls, read the Turbo C manual.  There
are some routines that are non-portable that you may use to do
console i/o.  Furthermore, there is a global flag that you can
set telling TC to go directly to the video ram.  I don't remember
the name of this flag at the moment.

-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232
unmvax.cs.unm.edu!bbx!bbxsda!scott