/* 871K EXAM - DRAW program with ellipse implemented */ /* COMPILER DIRECTIVES */ #include #include #include #include #define TITLE 22 /* Number of characters in the title */ #define NUMBER(array) sizeof(array)/sizeof(array[0]) #define TRUE 1 #define FALSE 0 #define HERC_G 99 #define CGA_G 4 #define EGA_G 13 #define VGA_G 18 #define BULLET 16 #define CURSOR 95 #define SPACE 32 #define BACKSPACE_KEY 8 #define ENTER_KEY 13 #define ESCAPE_KEY 27 #define FLINE 0 #define FCIRCLE 1 #define FRECTANGLE 2 #define FELLIPSE 3 /* NEW DEFINITION for saving/retrieving purposes */ /* FUNCTION PROTOTYPES */ void Delay(int); void Comment_Line(char); int Get_Choice(int,int,int,int); void Make_Menu(int,int,int,int,int,int); void Graphics_Setup(); void Clean_Slate(); void Input_Box(); void File_IO(int); int Get_Coords(int); void Canvas_Restore(); void Shape_Maker(int); void Line_Maker(int); /* DECLARATION OF GLOBAL VARIABLES */ int choices[2], cursor_x, cursor_y, color; char menu_buf[2][120][64]; int menu_para[2][4]; int element_buffer[4000], element_pntr, bufull_flag; char filename[26]="DRAW.DAT"; struct vconfig screen; /* Holds xpixels, ypixels, textcols, textrows, colors, bitsperpixel, pages, colormask, aspect_v, aspect_h */ char clean[6][6]= {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}}; char *menu_items[4][5] = {{"MAIN MENU","Lines","Shapes","Files","Exit"}, {"LINES","Draw","Endpoints","",""}, {"SHAPES","Circle","Rectangle","Ellipse",""}, {"FILES","Save","Save as","Get",""}}; /* FUNCTION DEFINITIONS */ main() /* Controling routine */ { int parent_x=16, parent_y=16, items, menu_number=0; int level=0, max_chars=11, items_count[4]={5,3,4,4}; char title="SIMPLE DRAWING PROGRAM"; int i, j, x, y; int menu_x, menu_y, right_edge, bottom_edge; /* Autodetection of graphics hardware and enter optimum graphics mode */ Graphics_Setup(); cursor_x=screen.xpixels/2; cursor_y=screen.ypixels/2; color=15; element_pntr=0; /* Create screen environment for menus */ pen_color(3); move_to(1,1); line_to(screen.xpixels-1,1); line_to(screen.xpixels-1,screen.ypixels-1); line_to(1,screen.ypixels-1); line_to(1,1); move_to(1,screen.ypixels-14); line_to(screen.xpixels-1,screen.ypixels-14); move_to(1,11); line_to(screen.xpixels-1,11); move_to(((screen.xpixels-(TITLE*8))/2),3); plots(title); pen_color(color); /* Begin main program control loop */ while(TRUE) { menu_number=0; level=0; items=items_count[menu_number]; Make_Menu(parent_x,parent_y,items,menu_number,level,max_chars); do { menu_number=0; level=0; items=items_count[menu_number]; menu_number=Get_Choice(parent_x, parent_y, items, level); choices[0]=menu_number; if (choices[0] == 4) { setvmode(DEFAULTMODE); exit(0); } level=1; items=items_count[menu_number]; Make_Menu(parent_x,parent_y,items,menu_number,level,max_chars); menu_number=Get_Choice(parent_x, parent_y, items, level); choices[1]=menu_number; /* Here the Esc key was hit, so restore screen area behind the menu */ if (menu_number == 0) { j=0; menu_x=menu_para[level][0]; menu_y=menu_para[level][1]; right_edge=menu_para[level][2]; bottom_edge=menu_para[level][3]; for(y=menu_y;y<=bottom_edge;y++){ i=0; for(x=menu_x;x<=right_edge;x++){ pen_color((int)menu_buf[level][i][j]); setpixel(x,y); i++; } j++; } } } while (menu_number == 0); /* Menu 1 */ if (choices[0]==1){ Canvas_Restore(); Line_Maker(choices[1]); } /* Menu 2 */ if (choices[0]==2){ Canvas_Restore(); Shape_Maker(choices[1]); } /* Menu 3 */ if (choices[0]==3){ Canvas_Restore(); File_IO(choices[1]); } } } Graphics_Setup() /* Autodetect and establish graphics mode */ { int mode; if(setvmode(VGA_G) == VGA_G) goto Graphics_mode; else if(setvmode(EGA_G) == EGA_G) goto Graphics_mode; else if(setvmode(CGA_G) == CGA_G) goto Graphics_mode; else if(setvmode(HERC_G) == HERC_G) goto Graphics_mode; else { printf("You don't have a graphics card installed"); exit(0); } Graphics_mode: getvconfig(&screen); mode=getvmode(); clrscrn2(0); return; } /* Put the menu on the screen */ Make_Menu(parent_x,parent_y,items,menu_number,level,max_chars) { int i, j, x, y, right_edge, bottom_edge; int menu_x=parent_x+level*24, menu_y=parent_y+level*24; int width=max_chars*8+16, height=items*8+16; j=0; right_edge=menu_x+width; bottom_edge=menu_y+height; menu_para[level][0]=menu_x; menu_para[level][1]=menu_y; menu_para[level][2]=right_edge; menu_para[level][3]=bottom_edge; /* Store what's underneath the menu */ for(y=menu_y;y<=bottom_edge;y++){ i=0; for(x=menu_x;x<=right_edge;x++){ menu_buf[level][i][j]=(char)getpixel(x,y); i++; } j++; } /* Make the menu boxes */ fill_style(clean,6,6); move_to(menu_x, menu_y); box(width, height, 1); move_to(menu_x+4, menu_y+4); box(width-8, height-8, 0); /* Write the menu items */ for(i=0;inumitems-2) choice_number=0; move_to(bullet_x, bullet_y); plotch(SPACE); bullet_y=parent_y+level*24+16+choice_number*8; move_to(bullet_x, bullet_y); plotch(BULLET); if (keyput == ESCAPE_KEY) { choice_number=-1; keyput = ENTER_KEY; } } move_to(bullet_x, bullet_y); plotch(SPACE); return choice_number+1; } Comment_Line(message) /* Print message on comment line at bottom of screen */ { move_to(8,screen.ypixels-10); fill_style(clean,6,6); flood(312,8); move_to(8,screen.ypixels-10); plots(message); } Delay(delay) /* Pause in execution */ { int i, j, a; for (i=0; i screen.xpixels-3) cursor_x=screen.xpixels-3; if (cursor_y < 13) cursor_y=13; if (cursor_y > screen.ypixels-16) cursor_y=screen.ypixels-16; if ((cursor_x!=old_cursor_x) || (cursor_y!=old_cursor_y)){ pen_color(pixel_buf[0]); setpixel(old_cursor_x-1,old_cursor_y); pen_color(pixel_buf[1]); setpixel(old_cursor_x,old_cursor_y); pen_color(pixel_buf[2]); setpixel(old_cursor_x+1,old_cursor_y); pen_color(pixel_buf[3]); setpixel(old_cursor_x,old_cursor_y-1); pen_color(pixel_buf[4]); setpixel(old_cursor_x,old_cursor_y+1); if (draw_flag && pen_flag) { if (element_pntr < NUMBER(element_buffer)-8*sizeof(int)) { pen_color(color); move_to(old_cursor_x, old_cursor_y); line_to(cursor_x, cursor_y); element_buffer[++element_pntr]=FLINE; element_buffer[++element_pntr]=old_cursor_x; element_buffer[++element_pntr]=old_cursor_y; element_buffer[++element_pntr]=cursor_x; element_buffer[++element_pntr]=cursor_y; } else { Comment_Line("*** Element buffer is full ***"); Delay(1000); keyput=ESCAPE_KEY; } } old_cursor_x=cursor_x; old_cursor_y=cursor_y; pixel_buf[0]=getpixel(cursor_x-1,cursor_y); pixel_buf[1]=getpixel(cursor_x,cursor_y); pixel_buf[2]=getpixel(cursor_x+1,cursor_y); pixel_buf[3]=getpixel(cursor_x,cursor_y-1); pixel_buf[4]=getpixel(cursor_x,cursor_y+1); } count+=16; if (count > 200) pen_color(wink_color); else pen_color(color); } pen_color(pixel_buf[0]); setpixel(cursor_x-1,cursor_y); pen_color(color); setpixel(cursor_x,cursor_y); pen_color(pixel_buf[2]); setpixel(cursor_x+1,cursor_y); pen_color(pixel_buf[3]); setpixel(cursor_x,cursor_y-1); pen_color(pixel_buf[4]); setpixel(cursor_x,cursor_y+1); pen_color(color); Comment_Line(" "); return(keyput); } Shape_Maker(menu_choice) { int center_x, center_y, edge_x1, edge_y1; int edge_x2, edge_y2, radius_x, radius_y; int width, height; if (element_pntr > NUMBER(element_buffer)-8*sizeof(int)) { Comment_Line("*** The element buffer is FULL ***"); return; } if (menu_choice == 1){ element_buffer[++element_pntr]=FCIRCLE; Comment_Line("Mark center of circle"); Get_Coords(0); element_buffer[++element_pntr]=cursor_x; element_buffer[++element_pntr]=cursor_y; center_x=cursor_x; center_y=cursor_y; setpixel(center_x,center_y); Comment_Line("Mark left or right edge of circle"); Get_Coords(0); move_to(center_x,center_y); radius_y=abs(cursor_x-center_x); element_buffer[++element_pntr]=radius_y; circle(radius_y,color); } if (menu_choice == 2) { element_buffer[++element_pntr]=FRECTANGLE; Comment_Line("Mark left-top corner of box"); Get_Coords(0); element_buffer[++element_pntr]=cursor_x; element_buffer[++element_pntr]=cursor_y; edge_x1=cursor_x; edge_y1=cursor_y; setpixel(edge_x1,edge_y1); Comment_Line("Mark right_bottom of box"); Get_Coords(0); height=cursor_y-edge_y1; width=cursor_x-edge_x1; move_to(edge_x1,edge_y1); box(width, height, 0); element_buffer[++element_pntr]=width; element_buffer[++element_pntr]=height; } if (menu_choice == 3) { element_buffer[++element_pntr]=FELLIPSE; Comment_Line("Mark center of ellipse"); Get_Coords(0); element_buffer[++element_pntr]=cursor_x; element_buffer[++element_pntr]=cursor_y; center_x=cursor_x; center_y=cursor_y; setpixel(center_x,center_y); Comment_Line("Mark left or right edge of ellipse"); Get_Coords(0); edge_x1=cursor_x; edge_y1=cursor_y; setpixel(edge_x1,edge_y1); radius_x=abs(cursor_x-center_x); element_buffer[++element_pntr]=radius_x; Comment_Line("Mark top or bottom edge of ellipse"); Get_Coords(0); radius_y=abs(cursor_y-center_y); element_buffer[++element_pntr]=radius_y; move_to(center_x,center_y); ellipse(radius_x,radius_y,color); } } Line_Maker(menu_choice) { int x1,y1,x2,y2,keyget=0; if (element_pntr > NUMBER(element_buffer)-8*sizeof(int)) { Comment_Line("*** The element buffer is FULL ***"); return; } if (menu_choice == 1) { Get_Coords(1); } if (menu_choice == 2){ while (keyget != ESCAPE_KEY) { element_buffer[++element_pntr]=FLINE; Comment_Line("Enter first endpoint, Esc to exit"); keyget=Get_Coords(0); element_buffer[++element_pntr]=cursor_x; element_buffer[++element_pntr]=cursor_y; setpixel(cursor_x,cursor_y); x1=cursor_x; y1=cursor_y; if (keyget != ESCAPE_KEY){ Comment_Line("Enter second endpoint, Esc to exit"); keyget=Get_Coords(0); element_buffer[++element_pntr]=cursor_x; element_buffer[++element_pntr]=cursor_y; x2=cursor_x; y2=cursor_y; move_to(x1,y1); line_to(x2,y2); } else element_pntr-=3; if (element_pntr > NUMBER(element_buffer)-8*sizeof(int)) { Comment_Line("*** The element buffer is FULL ***"); } } } } Input_Box() { int keyget, cursor_pntr=0; Comment_Line("Input filename: "); while (keyget != ENTER_KEY) { keyget=getch(); if ((keyget == BACKSPACE_KEY) && (cursor_pntr >0)) { plotch(SPACE); move_by(-16,0); plotch(CURSOR); move_by(-8,0); --cursor_pntr; } if (keyget == ESCAPE_KEY) { keyget=ENTER_KEY; filename[0]=0; Comment_Line(" "); } if ((isalnum(keyget) || isgraph(keyget)) && cursor_pntr < 25) { plotch(keyget); plotch(CURSOR); move_by(-8,0); filename[cursor_pntr++]=keyget; } } filename[cursor_pntr]=0; return(&filename); Comment_Line(" "); } File_IO(menu_choice) { int i, number_items; int center_x, center_y, edge_x1, edge_y1; int edge_x2, edge_y2, radius_x, radius_y; int x1,y1,x2,y2,keyget=0; if (menu_choice == 1){ FILE *fp; size_t count; element_buffer[0]=element_pntr+1; fp = fopen(filename,"wb"); if (fp != NULL) { count = fwrite(element_buffer,sizeof(int),NUMBER(element_buffer),fp); if (count == NUMBER(element_buffer)) Comment_Line("File saved"); else Comment_Line("*** Couldn't save file ***"); } fclose(fp); Clean_Slate(); element_pntr=0; Delay(600); Comment_Line(" "); } if (menu_choice == 2){ FILE *fp; size_t count; element_buffer[0]=element_pntr+1; Input_Box(); if (filename[0] == 0) return; fp = fopen(filename,"wb"); if (fp != NULL) { count = fwrite(element_buffer,sizeof(int),NUMBER(element_buffer),fp); if (count == NUMBER(element_buffer)) Comment_Line("File saved"); else Comment_Line("*** Couldn't save file ***"); } fclose(fp); Clean_Slate(); element_pntr=0; Delay(600); Comment_Line(" "); } if (menu_choice == 3){ FILE *fp; Input_Box(); if (filename[0] == 0) return; fp = fopen(filename,"rb"); if (fp == NULL) { Comment_Line("*** Could not open file ***"); return(0); } Comment_Line("Reading file"); fread(element_buffer, sizeof(int), 1, fp); number_items=element_buffer[0]; fclose(fp); fp = fopen(filename,"rb"); fread(element_buffer, sizeof(int), number_items, fp); fclose(fp); element_pntr=1; Comment_Line("Clearing off the board "); Clean_Slate(); Comment_Line(" "); while (element_pntr < number_items){ if (element_buffer[element_pntr] == FCIRCLE){ center_x=element_buffer[++element_pntr]; center_y=element_buffer[++element_pntr]; radius_y=element_buffer[++element_pntr]; move_to(center_x,center_y); circle(radius_y,color); ++element_pntr; } if (element_buffer[element_pntr] == FLINE){ x1=element_buffer[++element_pntr]; y1=element_buffer[++element_pntr]; x2=element_buffer[++element_pntr]; y2=element_buffer[++element_pntr]; move_to(x1,y1); line_to(x2,y2); ++element_pntr; } if (element_buffer[element_pntr] == FRECTANGLE){ x1=element_buffer[++element_pntr]; y1=element_buffer[++element_pntr]; x2=element_buffer[++element_pntr]; y2=element_buffer[++element_pntr]; move_to(x1,y1); box(x2,y2,0); ++element_pntr; } if (element_buffer[element_pntr] == FELLIPSE){ center_x=element_buffer[++element_pntr]; center_y=element_buffer[++element_pntr]; radius_x=element_buffer[++element_pntr]; radius_y=element_buffer[++element_pntr]; move_to(center_x,center_y); ellipse(radius_x,radius_y,color); ++element_pntr; } } element_pntr=number_items-1; } } Clean_Slate(void) { move_to(4,12); line_to(screen.xpixels-4,screen.ypixels-20); move_to(4,screen.ypixels-20); line_to(screen.xpixels-4,12); move_to(2,12); flood(screen.xpixels-4, screen.ypixels-26); }