Close Back

      1  /*
      2  *	head.h
      3  *
      4  *****************************************************************************
      5  *
      6  *	Dynamic Heading for C Programs
      7  *     	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      8  *****************************************************************************
      9  *
     10  *     	Author           :  Rajesh _ThE gReAt
     11  *	Built on         :  Tuesday,January  21, 2002, 9:59:31 AM
     12  *	Last Modified on :  Friday, February 08, 2002, 3:27:40 PM
     13  *
     14  *	Known errors : Since the fuction load() captures timer interrupt
     15  *                      it must be used with caution.
     16  *                      Also , the first argument to load is modified if 
     17  *                      it contains newlines or TABS.
     18  *
     19  *****************************************************************************
     20  *	DISCLAIMER:
     21  *****************************************************************************
     22  *
     23  *	Programmers may incorporate any or all code into their programs,
     24  *	giving proper credit within the source. Publication of the
     25  *	source routines is permitted so long as proper credit is given
     26  *	to Rajesh _ThE gReAt.
     27  *
     28  *	Copyright (C) 2002, 2003 by Rajesh _ThE gReAt.  You may use this program, or
     29  *	code or tables extracted from it, as desired without restriction.
     30  *	I can not and will not be held responsible for any damage caused from
     31  *	the use of this software.
     32  *
     33  *	Read license.txt from http://www.rajeshgoli.com/license.txt
     34  *	                   or http://www.rajeshgoli.com/license.htm
     35  *	before using / distributing / or any sort of use of my source
     36  *	Also read my disclaimer http://www.rajeshgoli.com/disclaimer.htm
     37  *	
     38  *	YOU AGREE TO BE BOUND BY MY DISCLAIMER AND LICENSE BY IN ANY WAY
     39  *	USING THIS FILE .
     40  *
     41  *****************************************************************************
     42  * This source works with Turbo C 2.0 and Turbo C++ 3.0 and above.
     43  *****************************************************************************
     44  *	Rajesh _ThE gReAt is a synonym of Rajesh Goli
     45  *	Source freely distributable 
     46  *****************************************************************************/
     47  
     48  /* For testing the header file
     49  */
     50  /*
     51  #define TEST_HEAD_H
     52  */
     53  
     54  /* Make this 1 if you want the interrupt our_timer to put
     55     the message chars too on VDU memory .
     56     Best leave it alone , it is not desirable ..
     57     Use loadtext() instead
     58  */
     59  #define PUT_MSG_TOO 0
     60  
     61  /* The VDU memory has the following structure for colors
     62     Bbbbffff in each byte 
     63     where B is blink bit
     64     bbb are backgound color bits
     65     ffff are foreground color bits
     66     This macro sets it
     67  */
     68  #define our_attrb(attrb,fattrb,battrb,blink) \
     69  (attrb) &= 0x00; \
     70  (attrb) |= ((fattrb) & 0x0F) ; \
     71  (attrb) |= (((battrb)<<4) & 0x70) ; \
     72  (attrb) |= (((blink)<<7) & ~0x7F);
     73  
     74  typedef unsigned char byte;
     75  
     76  #ifndef __HEAD_H
     77  #define __HEAD_H
     78  #endif
     79  
     80  #ifndef __DOS_H
     81  #include <dos.h>
     82  #endif
     83  
     84  /* Returned vaules by load() if an error occurs
     85  */
     86  /* The x and/or y values are not valid */
     87  #define X_Y_ERROR -1
     88  /* A string is already being highlighted */
     89  #define LOADED_ERROR -2
     90  /* Attributes supplied are invalid */
     91  #define ATTRB_ERROR -3
     92  
     93  /* First location of VDU memory */
     94  byte far *scr = (byte far *)0xB0008000;
     95  
     96  #if( PUT_MSG_TOO == 1)
     97  char *message;
     98  #endif
     99  
    100  unsigned len,clk,cnt,wait_for;
    101  byte hcolor,normcolor;
    102  short loaded = 0;
    103  
    104  /* Function ( or poiner to function ) prototypes */
    105  int load(char *,byte ,byte ,byte ,unsigned ,unsigned short ,unsigned short );
    106  void unload( void );
    107  int chkattrb(byte );
    108  unsigned conv(float ,short );
    109  void loadtext(const char *msg);
    110  void changeattr(byte ,byte ,byte ,short );
    111  void interrupt (*prev_0x08)();
    112  void interrupt our_timer();
    113  
    114  /* This function can be called only once during the execution , unless there 
    115     is a call to unload ();
    116  */
    117  /* msg      = string to be displayed , No NewLines or TABS allowed
    118                first instance of Newline or TAB found is replaced
    119                by '\0'
    120     attrb    = color of text ( normal )
    121     hattrb   = color of text ( highlighted )
    122     battrb   = The color of background of char (normal & Highlighted)
    123     wait_cnt = 1 means 1/18.2 part of a second
    124                2 means 2/18.2 part of a second
    125                It specifies the period during which a char remains highlighted
    126     x        = x co-ordinate of starting postion of string
    127     y        = y co-ordinate of starting postion of string
    128  */
    129  int load(char *msg,byte attrb,byte hattrb,byte battrb,unsigned wait_cnt,unsigned short x,unsigned short y)
    130  {
    131  	int i;
    132  	
    133  	/* A message is already loaded , timer is already captured once 
    134             another capture might lead to its slowdown and also system
    135  	   instability , so prevent it*/
    136  	if(loaded == 1)
    137  		return LOADED_ERROR;
    138  
    139  	/* Find NewLine , if any replace it by NULL */
    140  	for(i = 0; msg[i] && msg[i] != '\n';i++);
    141  	if(msg[i] == '\n' || msg[i] == '\t')
    142  		msg[i] = 0;
    143  
    144  	/* Find out lenght of string including the terminating NULL */
    145  	i = 0;
    146  	while(msg[i++]);
    147  	len = i - 1; /* -1 to remove the trailing NULL */
    148  
    149  	/* If we are given illegal x or y or
    150             we are given x such that we cannot accomodate string
    151             within a single line then return error code
    152  	*/
    153  	if(x< 1 || x > (80 - len + 1) || y < 1 || y > 25)
    154  		return X_Y_ERROR;
    155  	
    156  	/* If we are given illegal attributes then return error code
    157  	*/
    158  	if(chkattrb(attrb) || chkattrb(hattrb) || chkattrb(battrb))
    159  		return ATTRB_ERROR;
    160  
    161  	/* Make the pointer point to first location
    162             where the string is to be written
    163  	*/
    164  	scr += ( ((x-1)*2) + ((y-1)*2*80) );
    165  
    166  	/* Set the colors
    167  	*/
    168  	our_attrb(normcolor,attrb,battrb,0);
    169  	our_attrb(hcolor,hattrb,battrb,0);
    170  
    171  	/* Copy the string to VDU memory
    172  	*/
    173  	for(i = 0 ; msg[i] ; i++)
    174  	{
    175  		*(scr+(i*2)) = msg[i];
    176  		*(scr+(i*2)+1) = normcolor;
    177  	}
    178  
    179  /* If the message is some how lost 
    180     say by printing newlines by other parts of program
    181     then this will come to rescue it will print the 
    182     string again
    183     Though this is not very desirable use loadtext()
    184     instead .
    185  */
    186  #if( PUT_MSG_TOO == 1)
    187  	message = msg;
    188  #endif
    189  
    190  	/* Initialise the variables needed by our_timer() */
    191  	clk = 0;
    192  	cnt = 0;
    193  	wait_for = wait_cnt;
    194  
    195  	/* Store previous interrupt */
    196  	prev_0x08 = getvect(0x08);
    197  	/* Put our timer to work */
    198  	setvect(0x08,our_timer);
    199  	
    200  	/* Flag variable to prevent calling load more than once */
    201  	loaded = 1;
    202  	return 1;
    203  }
    204  
    205  short active = 0 ,on = 0;
    206  
    207  /* Call this b4 calling load() again
    208     or b4 exiting the program to clean up
    209  */
    210  void unload()
    211  {
    212  	if(loaded != 1)
    213  		return;
    214  	/* Set back the previous timer */
    215  	setvect(0x08,prev_0x08);
    216  	/* If some char is still highlighted
    217             make it normal
    218  	*/
    219  	if(on)
    220  	{
    221  		*(scr + cnt*2 + 1) = normcolor;
    222  	}
    223  	/* Flag reset */
    224  	loaded = 0;
    225  	return;
    226  }
    227  
    228  /*
    229     DO NOT EDIT THIS FUNCTION UNLESS YOU KNOW WHAT YOU ARE DOING
    230     I CANNOT BE HELD RESPONSIBLE FOR ANY PROBLEM CAUSED BY USING
    231     AND/OR MODIFING THIS FUNCTION
    232  */
    233  void interrupt our_timer()
    234  {
    235  	/* We've waited long enough */
    236  	if(clk == wait_for)
    237  	{
    238  		/* If this is already active , no point in using this */
    239  		if(!active)
    240  		{
    241  			/* Flag to indicate that this portion is active */
    242  			active = 1;
    243  			/* Some char is highlighted */
    244  			if(on)
    245  			{
    246  				on = 0;
    247  
    248  		#if( PUT_MSG_TOO == 1 )
    249  				*(scr + cnt*2) = message[cnt];
    250  		#endif
    251  
    252  				/* Reset the highlighted char */
    253  				*(scr + cnt*2 + 1) = normcolor;
    254  				/* Point to next char of string */
    255  				cnt++;
    256  				/* reset flag */
    257  				active = 0;
    258  				/* This HAS to be called anyway ... */
    259  				(*prev_0x08)() ;
    260  				/* End the present call */
    261  				return;
    262  			}
    263  			/* too long ;) */
    264  			if(cnt == len)
    265  				cnt = 0;
    266  
    267  	#if( PUT_MSG_TOO == 1 )
    268  			*(scr + cnt*2) = message[cnt];
    269  	#endif
    270  			/* Highlight msg[cnt] */
    271  			*(scr + cnt*2 + 1) = hcolor;
    272  			/* Tell the program a char is highlighted */
    273  			on = 1;
    274  			/* reset flag */
    275  			active = 0;
    276  			/* start a fresh count */
    277  			clk = 0;
    278  		}
    279  		/* The part is already active
    280  		   is wait_for too short?
    281                     Anyway reset clock , begin a new count
    282  		*/ 
    283  		else
    284  			clk = 0;
    285  	}
    286  	/* We havent waited long enough */
    287  	else
    288  		clk++;
    289  	/* This HAS to be called anyway ... */
    290  	(*prev_0x08)();
    291  }
    292  
    293  /* Function to check weather the provided attributes
    294     are valid
    295  */
    296  int chkattrb(byte attrb)
    297  {
    298  	if(attrb > 15)
    299  		return 1;
    300  	else
    301  		return 0;
    302  }
    303  
    304  #define SEC  1
    305  #define mSEC 2
    306  
    307  /* A fuction to convert seconds or milliseconds
    308     to the type of unit required by load()
    309  
    310     how_may   = how many secs or millisecs
    311     what_type = SEC or mSEC
    312  */
    313  unsigned conv(float how_many,short what_type)
    314  {
    315  	float tim_sec;
    316  	if(how_many <= 0)
    317  		return 0;
    318  	if(what_type != SEC && what_type != mSEC)
    319  		return 0;
    320  	if(what_type == SEC)
    321  	{
    322  		tim_sec = how_many;
    323  		tim_sec *= 18.2;
    324  		if(tim_sec >= 0 && tim_sec <= 1)
    325  			return 1;
    326  		else
    327  		{
    328  			if(tim_sec - (float)(int)(tim_sec) < 0.5)
    329  				return ((unsigned)tim_sec);
    330  			else
    331  				return ((unsigned)tim_sec + 1);
    332  		}
    333  	}
    334  	if(what_type == mSEC)
    335  	{
    336  		tim_sec = how_many;
    337  		tim_sec /= 1000; /* convert to Secs */
    338  		tim_sec *= 18.2;
    339  		if(tim_sec >= 0 && tim_sec <= 1)
    340  			return 1;
    341  		else
    342  		{
    343  			if(tim_sec - (float)(int)(tim_sec) < 0.5)
    344  				return ((unsigned)tim_sec);
    345  			else
    346  				return ((unsigned)tim_sec + 1);
    347  		}
    348  	}
    349  }
    350  
    351  /* If u clrscr() once when load is active,
    352     instead of unload()ing and load()ing again ,
    353     use this .
    354  */
    355  void loadtext(const char *msg)
    356  {
    357  	int i;
    358  
    359  	/* load() is not called yet!
    360  	*/
    361  	if(loaded != 1)
    362  		return;
    363  
    364  	/* Copy the string to VDU memory
    365  	*/
    366  	for(i = 0 ; msg[i] ; i++)
    367  	{
    368  		*(scr+(i*2)) = msg[i];
    369  		*(scr+(i*2)+1) = normcolor;
    370  
    371  	}
    372  	return;
    373  }
    374  
    375  /* change attributes of message while load() is still active
    376     usefull if u want the chars to blink , there is no option
    377     for this in load()
    378  */
    379  void changeattr(byte fore,byte hlgt,byte bak,short blink)
    380  {
    381  	our_attrb(normcolor,fore,bak,blink);
    382  	our_attrb(hcolor,hlgt,bak,blink);
    383  	return;
    384  }
    385  
    386  #ifdef TEST_HEAD_H
    387  
    388  #include<conio.h>
    389  #include<string.h>
    390  
    391  /* This is for checking
    392  */
    393  void main()
    394  {
    395  	clrscr();
    396  	load("http://www.rajeshgoli.com",GREEN,LIGHTGREEN,BLACK,3,80/2-strlen("http://www.rajeshgoli.com")/2,2);
    397  	gotoxy(10,10);
    398  	while(!kbhit());
    399  	getch();
    400  	unload();
    401  	printf("\nHit a key ...");
    402  	getch();
    403  	clrscr();
    404  }
    405  
    406  #endif