_AN ICON EDITOR_ by Keith Weiskamp and Loren Heiny [LISTING ONE] /* iconed.c -- a special purpose icon editor. * * This program allows you to interactively edit icons that * can be used in a graphics program. You can create an icon, * edit an existing one, or save an icon pattern to a file. The * program requires a mouse. The icon files produced are of the * form: * ICONWIDTH ICONHEIGHT * one row of icon pattern * next row of icon pattern * . . . * last row of icon pattern * */ #include #include #include #include #include #include #include "mouse.h" /* mouse and keyboard routines */ #define BIGICONLEFT 20 /* left side of the big icon pattern */ #define BIGICONTOP 50 /* top side of the big icon pattern */ #define BIGBITSIZE 8 /* big bits are 8 pixels in size */ #define ICONWIDTH 16 /* an icon is a 16x16 pattern */ #define ICONHEIGHT 16 #define ICONLEFT 400 /* small icon pattern located here */ #define ESC 27 /* the value of the ESC key */ /* Here are the functions used in iconed.c: */ void draw_enlarged_icon(void); void toggle_bigbit(int x, int y); void toggle_icons_bit(int x, int y); void init_bigbit(void); void toggle_cursor(int x, int y); void save_icon(void); int read_icon(void); void init_graphics(void); void show_icon(void); /* The global variables */ void *bigbit; /* points to image of a big bit */ /* holds icon pattern */ unsigned char icon[ICONHEIGHT][ICONWIDTH]; void main() { int x, y; int c; read_icon(); /* read in an icon file */ init_graphics(); /* initialize mouse */ if (!initmouse()) { /* must have mouse */ restorecrtmode(); printf("\nMouse not installed"); printf("\nQuitting the Icon Editor"); exit(1); } draw_enlarged_icon(); /* an empty big icon pattern */ show_icon(); /* Draw the icon */ hidemouse(); /* mouse cursor must be turned off */ /* before writing to screen */ outtextxy(BIGICONLEFT, 10, "Press ESC when finished ..."); outtextxy(BIGICONLEFT, BIGICONTOP-20, "Enlarged Icon"); outtextxy(ICONLEFT, BIGICONTOP-20, "Actual Icon"); showmouse(); /* redisplay mouse cursor */ /* get input from mouse/keyboard */ while ((c=waitforinput(LEFT_BUTTON)) != ESC) { if (c < 0) { /* if true mouse button pressed */ getmousecoords(&x, &y); /* get current position */ toggle_bigbit(x, y); /* toggle big bit */ } } hidemouse(); /* turn mouse off and then get out */ closegraph(); /* of graphics mode */ printf("Do you want to save this icon to a file? (y) "); if (getch() != 'n') save_icon(); } void draw_enlarged_icon(void) { /* * This function draws an enlarged view of the icon pattern. * You can click a big bit in this pattern to toggle the * corresponding icons on and off in the actual icon. The * icon is drawn at BIGICONLEFT, BIGICONTOP, to right, bottom. */ int i; int right,bottom; setlinestyle(DOTTED_LINE, 0, NORM_WIDTH); right = 2 * (BIGICONLEFT + (ICONWIDTH-1) * (BIGBITSIZE + NORM_WIDTH)); bottom = BIGICONTOP + ICONHEIGHT * (BIGBITSIZE + NORM_WIDTH); hidemouse(); /* draw vertical and horizonatal dashed */ for (i=0; i<=ICONHEIGHT; i++) line(BIGICONLEFT, BIGICONTOP+i*(BIGBITSIZE+NORM_WIDTH), right, BIGICONTOP+i*(BIGBITSIZE+NORM_WIDTH)); for (i=0; i<=ICONWIDTH; i++) line(BIGICONLEFT+2*(i*(BIGBITSIZE+NORM_WIDTH)), BIGICONTOP, BIGICONLEFT+2*(i*(BIGBITSIZE+NORM_WIDTH)), bottom); showmouse(); init_bigbit(); /* create the big bit image */ } void init_bigbit(void) { /* This function creates the image of a single big bit. This * image is used to toggle the big bits whenever the user * clicks on the big icon pattern. */ int bbx, bby; int i,j; bbx = BIGICONLEFT; bby = BIGICONTOP; /* corner of the big icon */ hidemouse(); /* hide the mouse before drawing */ for (j=bby+1; j<=bby+BIGBITSIZE; j++) { for (i=bbx+1; i<=bbx+2*BIGBITSIZE; i++) { putpixel(i,j,getmaxcolor()); } } /* Set aside memory for the big bit image and then use getimage() to capture its image. */ bigbit = malloc(imagesize(bbx,bby,bbx+2*BIGBITSIZE, bby+BIGBITSIZE)); getimage(bbx+1,bby+1,bbx+2*BIGBITSIZE,bby+BIGBITSIZE, bigbit); /* Erase the big bit by exclusive ORing it with itself */ putimage(bbx+1, bby+1, bigbit, XOR_PUT); showmouse(); /* turn the mouse back on */ } void toggle_bigbit(int x, int y) { /* * This function toggles a big bit and the corresponding pixel * in the icon pattern. The x and y coordinates specify the * mouse position. */ int i, j; int line1, line2, col1, col2; for (j=0; j #include #include "mouse.h" #include "graphics.h" #define TRUE 1 #define FALSE 0 int mouseexists; /* internal variable set true if a */ /* mouse driver is detected */ void mouse(int *m1, int *m2, int *m3, int *m4) { /* * This function provides the interface between the mouse * driver and an application program. Several predefined mouse * functions supported by the Microsoft mouse are available. * Parameters are passed and returned with the ax, bx, cx and * dx registers. */ union REGS inregs, outregs; inregs.x.ax = *m1; inregs.x.bx = *m2; inregs.x.cx = *m3; inregs.x.dx = *m4; int86(0x33, &inregs, &outregs); *m1 = outregs.x.ax; /* return parameters */ *m2 = outregs.x.bx; *m3 = outregs.x.cx; *m4 = outregs.x.dx; } int initmouse(void) { /* * This function initializes the mouse and displays * the mouse cursor at the top, left of the screen, if one * is present. */ int m1, m2, m3, m4, gmode; char far *memory = (char far *)0x004000049L; mouseexists = TRUE; m1 = RESET_MOUSE; mouse(&m1, &m2, &m3, &m4); if (m1) { /* if mouse reset okay, assume */ gmode = getgraphmode(); /* mouse exists */ if (gmode == HERCMONOHI) { /* Test for Hercules */ *memory = 0x06; } m1 = SET_MOUSE_COORD; mouse(&m1, &m2, &m3, &m4); /* mouse exists and draw the */ showmouse(); /* cursor on the screen at 0,0 */ return(1); /* return a success flag */ } else { /* no mouse installed */ mouseexists = FALSE; return(0); /* return a no-mouse found flag */ } } void hidemouse(void) { /* This function removes the mouse cursor from the screen. It * should be called before displaying data on the screen. * Use showmouse() to redisplay the mouse cursor. The mouse * cursor still moves even though it is not visible. Don't * call hidemouse() if the mouse is not already visible. */ int m1, m2, m3, m4; if (mouseexists) { /* check for mouse */ m1 = HIDE_MOUSE; /* hide the mouse cursor */ mouse(&m1, &m2, &m3, &m4); } } void showmouse(void) { /* This function displays the mouse cursor. You should not call * this function if the mouse is already visible. */ int m1, m2, m3, m4; if (mouseexists) { /* make sure mouse exists */ m1 = SHOW_MOUSE; mouse(&m1, &m2, &m3, &m4); /* display mouse cursor */ } } void getmousecoords(int *x, int *y) { /* * This function returns the position of the mouse cursor. */ int m1, m2; if (mouseexists) { m1 = GET_MOUSE_STATUS; mouse(&m1, &m2, x, y); /* adjust for virtual coordinates */ if (getmaxx() == 319) (*x) /= 2; } } int testbutton(int testtype, int whichbutton) { /* * This function tests a mouse button state. It returns TRUE * if the specified mouse button (whichbutton) meets the * specified action (as indicated by testtype); otherwise the * function returns FALSE. */ int m1, m2, m3, m4; m1 = testtype; if (whichbutton == LEFT_BUTTON || whichbutton == EITHER_BUTTON) { m2 = LEFT_BUTTON; mouse(&m1, &m2, &m3, &m4); if (m2) return(TRUE); /* return TRUE if action ok*/ } if (whichbutton == RIGHT_BUTTON || whichbutton == EITHER_BUTTON) { m1 = testtype; m2 = RIGHT_BUTTON; mouse(&m1, &m2, &m3, &m4); if (m2) return(TRUE); /* return TRUE if action ok */ } return(FALSE); /* return FALSE as a catch all */ } int waitforinput(int whichbutton) { /* This function returns a character if a key has been pressed, * -1 if a mouse button has been pressed; otherwise a zero. If a mouse exists, this routine favors any keyboard action. */ int c = 0; while (!c) { if (kbhit()) /* check if a key has been pressed */ c =getch(); /* return the character */ else { if (testbutton(CHECK_BUTTON_PRESS, whichbutton)) { while (!testbutton(CHECK_BUTTON_RELEASE, whichbutton)); c = -1; } else if (testbutton(CHECK_BUTTON_RELEASE, whichbutton)) { c = -1; } } } return(c); } [LISTING THREE] /* mouse.h -- this file includes function prototypes and macro * constants for the functions in mouse.c. */ /* The following is a list of constants that correspond to the * mouse functions supported in mouse.c. */ #define RESET_MOUSE 0 #define SHOW_MOUSE 1 #define HIDE_MOUSE 2 #define GET_MOUSE_STATUS 3 #define SET_MOUSE_COORD 4 #define CHECK_BUTTON_PRESS 5 #define CHECK_BUTTON_RELEASE 6 #define SET_MOUSE_HORIZ_RANGE 7 /* not used */ #define SET_MOUSE_VERT_RANGE 8 /* not used */ #define SET_GRAPHICS_CURSOR 9 /* not used */ #define GET_MOUSE_MOVEMENT 11 #define SET_MICKEY_RATIO 15 /* not used */ #define LEFT_BUTTON 0 /* use left button */ #define RIGHT_BUTTON 1 /* use right button */ #define EITHER_BUTTON 2 /* use either button */ /* The function prototypes for the functions in mouse.c */ void mouse(int *m1, int *m2, int *m3, int *m4); int initmouse(void); void getmousecoords(int *x, int *y); void hidemouse(void); void showmouse(void); int testbutton(int testtype, int whichbutton); int waitforinput(int whichbutton);