home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_11_08
/
weber
/
region.c
< prev
next >
Wrap
Text File
|
1993-03-13
|
18KB
|
469 lines
/***************************************************************
* file: REGION.C
* purpose: Demonstration of region finding with cellular automata
* system: Written for the flash graphics library in Zortech 3.0
* copyright: 1992 by David Weber. All rights reserved.
* This software can be used for any purpose as object, library or executable.
* It cannot be sold for profit as source code.
* history:
* 01-13-92 - initial code
* 01-31-93 - the gui code is now obsolete, see the CPP gui package
**************************************************************/
#define MSDOS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "display.h"
#include "gui.h"
#include "loadsave.h"
#include "zone.h"
/* exit values */
#define EXIT_OK 0
#define EXIT_NO_GRAPHICS 1
/* graphics format types */
#define AUTO 0
#define CCITT4 1
#define CCITT3 2
#define PCX 3
#define TIFF 4
#define GIF 5
#define BMP 6
/* local data */
static char dir_search[FILENAME_MAX+1] = ".\\*.pcx";
static char file_choice[FILENAME_MAX+1];
static short format_open = PCX;
static short format_save = CCITT4;
static short density_value = 2;
static short zones_displayed = 0;
/* local prototypes */
static short dispatch_message(MESSAGE *message);
static short dialog_format_handler(short dialog_type);
static short dialog_number_handler(short *current,short minimum,short maximum,short dx,short dy);
static void draw_slider(short value,short minimum,short maximum);
static short dialog_help_handler(void);
/* menu bar data */
/* menu ids */
#define M_FILE 300
#define M_FILE_OPEN 301
#define M_EDIT 400
#define M_ZONE 401
#define M_OPTIONS 500
#define M_SETDENSITY 501
#define M_ORDER 502
#define M_HELP 600
/* menu components */
static POPUP_ITEM file_popup[] =
{
{M_FILE_OPEN,"Open Ctrl+O",CTRLO,MENU_ACTIVE},
{M_QUIT,"Quit Ctrl+Q",CTRLQ,MENU_ACTIVE}
};
#define SHOW_MENU_POSITION 0
static POPUP_ITEM edit_popup[] =
{
{M_ZONE,"Show Zones Ctrl+Z",CTRLZ,MENU_GRAY}
};
static char row_order[] = "Row Major Order Ctrl+T";
static char column_order[] = "Column Major Order Ctrl+T";
#define ORDER_MENU_POSITION 1
static POPUP_ITEM option_popup[] =
{
{M_SETDENSITY,"Set Zone Density Ctrl+D",CTRLD,MENU_ACTIVE},
{M_ORDER,column_order,CTRLT,MENU_ACTIVE}
};
static MENU_ITEM menubar[] =
{
{M_FILE,"&File",ALTF,&file_popup[0],sizeof(file_popup)/sizeof(POPUP_ITEM),MENU_ACTIVE},
{M_OPTIONS,"&Edit",ALTE,&edit_popup[0],sizeof(edit_popup)/sizeof(POPUP_ITEM),MENU_ACTIVE},
{M_OPTIONS,"&Options",ALTO,&option_popup[0],sizeof(option_popup)/sizeof(POPUP_ITEM),MENU_ACTIVE},
{M_HELP,"&Help",ALTH,NULL,0,MENU_ACTIVE}
};
/* format button and dialog */
#define D_FORMAT_OPEN 1000
static BUTTON format_button_open = {D_FORMAT_OPEN,"&Format",ALTF,0,0,DIALOG_ACTIVE};
#define D_FORMAT_SAVE 1001
static BUTTON format_button_save = {D_FORMAT_SAVE,"&Format",ALTF,0,0,DIALOG_ACTIVE};
#define D_FORMAT_WIDTH (16*DIALOG_UNITS)
#define D_FORMAT_HEIGHT (11*DIALOG_UNITS)
#define D_FORMAT_RADIOBUTTON 1100
#define D_FORMAT_MIN_TYPE 1101 /* the following sequence must track the graphic format types */
#define D_FORMAT_AUTO 1101
#define D_FORMAT_CCITT4 1102
#define D_FORMAT_CCITT3 1103
#define D_FORMAT_PCX 1104
#define D_FORMAT_TIFF 1105
#define D_FORMAT_GIF 1106
#define D_FORMAT_BMP 1107
#define D_FORMAT_MAX_TYPE 1199 /* end of format type sequence */
#define D_FORMAT_OK 1200
#define D_FORMAT_CANCEL 1300
static BUTTON format_choices[] =
{
{D_FORMAT_AUTO,"Auto",ALT1,4*DIALOG_UNITS,9*DIALOG_UNITS,DIALOG_GRAY},
{D_FORMAT_CCITT4,"CCITT4",ALT2,4*DIALOG_UNITS,8*DIALOG_UNITS,DIALOG_GRAY},
{D_FORMAT_CCITT3,"CCITT3",ALT3,4*DIALOG_UNITS,7*DIALOG_UNITS,DIALOG_GRAY},
{D_FORMAT_PCX,"PCX",ALT4,4*DIALOG_UNITS,6*DIALOG_UNITS,DIALOG_ACTIVE|DIALOG_SELECTED},
{D_FORMAT_TIFF,"TIFF",ALT5,4*DIALOG_UNITS,5*DIALOG_UNITS,DIALOG_GRAY},
{D_FORMAT_GIF,"GIF",ALT6,4*DIALOG_UNITS,4*DIALOG_UNITS,DIALOG_GRAY},
{D_FORMAT_BMP,"BMP",ALT7,4*DIALOG_UNITS,3*DIALOG_UNITS,DIALOG_GRAY}
};
static RADIOBUTTON format_radiobutton = {D_FORMAT_RADIOBUTTON,sizeof(format_choices)/sizeof(BUTTON),format_choices,DIALOG_ACTIVE};
static BUTTON format_cancel = {D_FORMAT_CANCEL,"Cancel",ESC,2*DIALOG_UNITS,DIALOG_UNITS,DIALOG_ACTIVE};
static BUTTON format_ok = {D_FORMAT_OK,"Ok",F10,D_FORMAT_WIDTH-4*DIALOG_UNITS,DIALOG_UNITS,DIALOG_ACTIVE};
static DIALOG_ITEM dialog_format[] =
{
{DIALOG_RADIOBUTTON,&format_radiobutton},
{DIALOG_BUTTON,&format_cancel},
{DIALOG_BUTTON,&format_ok}
};
/* number dialog */
#define D_NUMBER_WIDTH 33 * DIALOG_UNITS
#define D_NUMBER_HEIGHT 8 * DIALOG_UNITS
#define NUMBER_EDIT_WIDTH 4
#define D_NUMBER 2000
#define D_NUMBER_OK 2001
#define D_NUMBER_CANCEL 2002
#define D_NUMBER_EDIT 2003
#define D_NUMBER_SLIDER 2004
#define D_NUMBER_LEFT 2005
#define D_NUMBER_RIGHT 2006
static char number_str[NUMBER_EDIT_WIDTH+1];
static TEXT number_title = {"Enter a new zone density:",1*DIALOG_UNITS,6*DIALOG_UNITS,DIALOG_ACTIVE};
static EDITBOX number_edit = {D_NUMBER_EDIT,27*DIALOG_UNITS,6*DIALOG_UNITS,NUMBER_EDIT_WIDTH*DIALOG_UNITS,NUMBER_EDIT_WIDTH,number_str,DIALOG_ACTIVE};
static TEXT number_min = {"0",8*DIALOG_UNITS+DIALOG_UNITS/2,4*DIALOG_UNITS,DIALOG_ACTIVE};
static BUTTON number_slider = {D_NUMBER_SLIDER," ",0,11*DIALOG_UNITS+DIALOG_UNITS/2,4*DIALOG_UNITS,DIALOG_GRAY};
static TEXT number_max = {"5",23*DIALOG_UNITS+DIALOG_UNITS/2,4*DIALOG_UNITS,DIALOG_ACTIVE};
static BUTTON number_left = {D_NUMBER_LEFT,"<<",'-',13*DIALOG_UNITS,2*DIALOG_UNITS,DIALOG_ACTIVE};
static BUTTON number_right = {D_NUMBER_RIGHT,">>",'+',18*DIALOG_UNITS,2*DIALOG_UNITS,DIALOG_ACTIVE};
static BUTTON number_cancel = {D_NUMBER_CANCEL,"Cancel",ESC,2*DIALOG_UNITS,DIALOG_UNITS,DIALOG_ACTIVE};
static BUTTON number_ok = {D_NUMBER_OK,"Ok",F10,D_NUMBER_WIDTH-4*DIALOG_UNITS,DIALOG_UNITS,DIALOG_ACTIVE};
static DIALOG_ITEM dialog_number[] =
{
{DIALOG_TEXT,&number_title},
{DIALOG_EDITBOX,&number_edit},
{DIALOG_TEXT,&number_min},
{DIALOG_BUTTON,&number_slider},
{DIALOG_TEXT,&number_max},
{DIALOG_BUTTON,&number_left},
{DIALOG_BUTTON,&number_right},
{DIALOG_BUTTON,&number_cancel},
{DIALOG_BUTTON,&number_ok}
};
/* help dialog */
#define D_HELP_WIDTH (50*DIALOG_UNITS)
#define D_HELP_HEIGHT (13*DIALOG_UNITS)
#define D_HELP_OK 3000
static TEXT help1 = {"This program demonstrates region detection on",1*DIALOG_UNITS,12*DIALOG_UNITS,DIALOG_ACTIVE};
static TEXT help2 = {"text pages using cellular automata. Follow",1*DIALOG_UNITS,11*DIALOG_UNITS,DIALOG_ACTIVE};
static TEXT help3 = {"these steps:",1*DIALOG_UNITS,10*DIALOG_UNITS,DIALOG_ACTIVE};
static TEXT help4 = {"1) Open a monochrome PCX file (File/Open).",1*DIALOG_UNITS,9*DIALOG_UNITS,DIALOG_ACTIVE};
static TEXT help5 = {"2) Display the regions (Edit/Show).",1*DIALOG_UNITS,8*DIALOG_UNITS,DIALOG_ACTIVE};
static TEXT help6 = {"3) Change the zone density (Option/Density)",1*DIALOG_UNITS,7*DIALOG_UNITS,DIALOG_ACTIVE};
static TEXT help7 = {"4) or change the ordering (Option/Order)",1*DIALOG_UNITS,6*DIALOG_UNITS,DIALOG_ACTIVE};
static TEXT help8 = {"and redisplay (Edit/Show) to see their effects.",1*DIALOG_UNITS,5*DIALOG_UNITS,DIALOG_ACTIVE};
static TEXT help9 = {"1993 - David Weber, Box 1376 Paonia CO 81428",1*DIALOG_UNITS,3*DIALOG_UNITS,DIALOG_ACTIVE};
static BUTTON help_ok = {D_HELP_OK,"Ok",ESC,24*DIALOG_UNITS,DIALOG_UNITS,DIALOG_ACTIVE};
static DIALOG_ITEM dialog_help[] =
{
{DIALOG_TEXT,&help1},
{DIALOG_TEXT,&help2},
{DIALOG_TEXT,&help3},
{DIALOG_TEXT,&help4},
{DIALOG_TEXT,&help5},
{DIALOG_TEXT,&help6},
{DIALOG_TEXT,&help7},
{DIALOG_TEXT,&help8},
{DIALOG_TEXT,&help9},
{DIALOG_BUTTON,&help_ok}
};
/* wherein all things commence */
short main()
{
MESSAGE message;
if (!gui_open()) /* fire up the graphics */
{
printf("Cannot initialize graphics display\n");
exit(EXIT_NO_GRAPHICS);
}
do /* loop on message stream */
{
if (message_get(&message) == M_QUIT)
if (yn_box("Are you sure"))
break;
} while (dispatch_message(&message));
display_free(); /* close down shop */
gui_close();
return EXIT_OK;
}
/* process messages, returns 1 if OK and 0 if fatal failure */
static short dispatch_message(MESSAGE *message)
{
short order;
switch (message->id)
{
case M_START: /* put up menu on start up */
if (!menu_open(menubar,sizeof(menubar)/sizeof(MENU_ITEM)))
{
error_box(gui_errno);
return 0;
}
break;
case M_FILE_OPEN: /* open file and display it */
loadsave_add_button(&format_button_open,dispatch_message);
if (loadsave(dir_search,file_choice,LOADSAVE_LOAD | LOADSAVE_VERIFY))
{
menu_clear(menubar);
if (display_file(file_choice))
{ /* activate zoning menu options */
edit_popup[SHOW_MENU_POSITION].status = MENU_ACTIVE;
}
else
{ /* clear zoning menu options */
edit_popup[SHOW_MENU_POSITION].status = MENU_GRAY;
}
zones_displayed = 0;
}
break;
case D_FORMAT_OPEN: /* get user format selection */
return dialog_format_handler(D_FORMAT_OPEN);
case M_ZONE:
if (option_popup[ORDER_MENU_POSITION].name == column_order)
order = COLUMN_MAJOR;
else
order = ROW_MAJOR;
if (!zone(density_value,order))
{
message_box("Out of Memory.");
break;
}
menu_clear(menubar);
if (zones_displayed)
display_redraw();
display_zones();
zones_displayed = 1;
break;
case M_SETDENSITY:
dialog_number_handler(&density_value,0,5,-1,-1);
break;
case M_ORDER:
if (option_popup[ORDER_MENU_POSITION].name == column_order)
option_popup[ORDER_MENU_POSITION].name = row_order;
else
option_popup[ORDER_MENU_POSITION].name = column_order;
menu_modify(menubar,M_ORDER,MENU_ACTIVE);
break;
case M_HELP:
dialog_help_handler();
break;
default: /* show possible error */
error_box(message->id);
break;
}
return 1;
}
/* handle the format dialog, returns 1 if OK or 0 if failure */
static short dialog_format_handler(short dialog_type)
{
MESSAGE message;
short temp_format,*format_storage,dx,dy;
dx = dy = -1;
if (dialog_type == D_FORMAT_SAVE) /* remove AUTO button for save */
{
format_storage = &format_save;
dialog_status_set(format_choices[0],DIALOG_INACTIVE);
loadsave_button_location(&format_button_save,&dx,&dy);
}
else /* replace AUTO button for open */
{
format_storage = &format_open;
dialog_status_set(format_choices[0],DIALOG_GRAY);
loadsave_button_location(&format_button_open,&dx,&dy);
}
if (dx >= 0 && dy >= 0) /* orient new dialog box */
{
dy -= D_FORMAT_HEIGHT;
if (dy < 0)
dy = 0;
}
radiobutton_set(&format_radiobutton,*format_storage+D_FORMAT_MIN_TYPE);
if (!dialog_open(dialog_format,sizeof(dialog_format)/sizeof(DIALOG_ITEM),dx,dy,D_FORMAT_WIDTH,D_FORMAT_HEIGHT))
return 0;
temp_format = *format_storage;
for (;;)
{
message_get(&message);
switch(message.id)
{
case D_FORMAT_OK: /* save format choice */
*format_storage = temp_format;
dialog_close(dialog_format);
return 1;
case D_FORMAT_CANCEL: /* reject format choice */
dialog_close(dialog_format);
radiobutton_set(&format_radiobutton,*format_storage+D_FORMAT_MIN_TYPE);
return 1;
case D_FORMAT_RADIOBUTTON: /* select format choice */
temp_format = message.data.short_data.x - D_FORMAT_MIN_TYPE;
break;
default:
if (error_box(message.id)) /* check if error */
{
dialog_close(dialog_format);
return 0;
}
break;
}
}
}
/* get a new number into value, returns 1 if OK or 0 if failure */
static short dialog_number_handler(short *current,short minimum,short maximum,short dx,short dy)
{
MESSAGE message;
short temp;
temp = *current;
sprintf(number_str,"%d",temp);
if (!dialog_open(dialog_number,sizeof(dialog_number)/sizeof(DIALOG_ITEM),dx,dy,D_NUMBER_WIDTH,D_NUMBER_HEIGHT))
return 0;
draw_slider(temp,minimum,maximum);
for (;;)
{
message_get(&message);
switch(message.id)
{
case D_NUMBER_CANCEL: /* reject changes */
dialog_close(dialog_number);
return 1;
case D_NUMBER_OK: /* save new number, fall through */
case D_NUMBER_EDIT: /* edit value */
temp = atoi(number_str);
if (message.id == D_NUMBER_EDIT && message.data.short_data.x != EDITBOX_ACCEPT)
{
if (temp > maximum)
temp = maximum;
else if (!isdigit(*number_str) || temp < minimum)
temp = minimum;
draw_slider(temp,minimum,maximum);
break;
}
if (temp < minimum || temp > maximum || !isdigit(*number_str))
{
message_box("Invalid Number");
temp = *current;
sprintf(number_str,"%d",temp);
editbox_initialize(&number_edit);
draw_slider(temp,minimum,maximum);
break;
}
*current = temp;
dialog_close(dialog_number);
return 1;
case D_NUMBER_LEFT: /* click slider left */
temp--;
if (temp < minimum)
temp = maximum;
sprintf(number_str,"%d",temp);
editbox_initialize(&number_edit);
draw_slider(temp,minimum,maximum);
break;
case D_NUMBER_RIGHT: /* click slider right */
temp++;
if (temp > maximum)
temp = minimum;
sprintf(number_str,"%d",temp);
editbox_initialize(&number_edit);
draw_slider(temp,minimum,maximum);
break;
default:
if (error_box(message.id)) /* check if error */
{
dialog_close(dialog_number);
return 0;
}
break;
}
}
}
/* draw the slider on the number_dialog */
static short empty_character = 176;
static short full_character = 219;
static void draw_slider(short value,short minimum,short maximum)
{
char *p;
short len,cell_height;
fg_box_t box;
if (fg.fontptr2 == (char _far *) NULL)
{ /* CGA has bogus characters 128-255 */
empty_character = '-';
full_character = '#';
}
p = number_slider.name;
len = strlen(p);
cell_height = gui_char_height + 6;
if (gui_char_height + gui_char_height/2 > cell_height)
cell_height = gui_char_height + gui_char_height/2;
fg_msm_hidecursor();
fg_box_cpy(box,number_slider.screen);
box[FG_X1] += gui_char_width;
box[FG_Y1] += (cell_height-gui_char_height)/2;
box[FG_X2] -= gui_char_width;
box[FG_Y2] = box[FG_Y1] + gui_char_height;
fg_fillbox(COLOR_DIALOG_BACKGROUND,FG_MODE_SET,~0,box);
value = (value*len)/(maximum-minimum) + minimum;
memset(p,empty_character,len);
memset(p,full_character,value);
fg_puts(COLOR_DIALOG_FOREGROUND,FG_MODE_SET,~0,FG_ROT0,box[FG_X1],box[FG_Y1],p,number_slider.screen);
fg_msm_showcursor();
fg_flush();
}
/* handle the help dialog */
static short dialog_help_handler(void)
{
MESSAGE message;
if (!dialog_open(dialog_help,sizeof(dialog_help)/sizeof(DIALOG_ITEM),-1,-1,D_HELP_WIDTH,D_HELP_HEIGHT))
return 0;
for (;;)
{
message_get(&message);
if (message.id == D_HELP_OK)
break;
}
dialog_close(dialog_help);
return 1;
}