home *** CD-ROM | disk | FTP | other *** search
- /* achat 4.0 June 4, 1995 */
-
- #include "vars.h" /* this into source, then comment out this line */
- /* if you have errors and you choose to block read */
- #pragma hdrstop
-
- #include <conio.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <dir.h>
-
-
-
-
-
- /* if NO_RANDOM_AT_START is defined, then the sysop will be prompted for */
- /* a chat screen upon entering the Asylum Chat */
- /* Leave it commented out to let the BBS randomly pick one for you */
- // #define NO_RANDOM_AT_START
-
-
- /* amount of lines it pulls up from the bottom when scrolling back to top */
- #define AMOUNT_TO_WRAP_UP (3)
-
-
-
- typedef struct
- {
- unsigned char xpos, ypos, length;
- } lines_record;
-
-
-
- typedef struct
- {
- int amount_colors;
-
- unsigned char colors[16]; /* up to 16 colors */
- } color_record;
-
-
- #define ACHAT_MAX_WIDTH 100
-
-
-
- #define AMOUNT_COLOR_SETS (5)
- const color_record colors[AMOUNT_COLOR_SETS] = {
- /* blue set */ { 4, 1, 9, 3, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* red set */ { 4, 4, 5, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* gray set */ { 4, 0, 7, 8, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* brwn set */ { 4, 3, 6, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- /* all clrs */ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }};
-
-
- static int sys_rand_color_set, user_rand_color_set;
-
- static lines_record *sys_lines, *user_lines;
- static char far *sys_text, *user_text, achat_dir[128]="";
-
- static int amount_sys_lines, amount_user_lines;
- static int sys_upper_color, sys_lower_color, sys_numeric_color;
- static int user_upper_color, user_lower_color, user_numeric_color;
-
- static int sys_bk_color, sys_rand_freq, sys_cur_color;
- static int user_bk_color, user_rand_freq, user_cur_color;
-
- static int sys_line, sys_pos, user_line, user_pos, alt_achat_clear;
- static int flip_sides, no_user_side, chat_done, pick_file;
-
- static int tl_x, tl_y, to_x, to_y, time_on_color=7, time_left_color=7;
- static int us_x, us_y, us_c=7, sy_x, sy_y, sy_c=7;
-
- static FILE *achat_desc;
-
- static char *welcome_text;
-
- void achat(char *sysop_name)
- {
- char fname[25], temp[50];
- int save_topdata = topdata;
- char WelcomeText[81];
-
-
- welcome_text = WelcomeText; /* save a few bytes of static storage */
- topdata=0;
- topscreen();
- CLS();
-
- flip_sides = 0;
- chat_done = 0;
-
- #ifndef NO_RANDOM_AT_START
- pick_file = 0; /* get a random ansi screen */
- #else
- pick_file = 1; /* prompt sysop for ansi screen name */
- #endif
-
-
- sprintf(achat_dir, "%sACHAT\\", syscfg.gfilesdir);
-
-
- #ifndef NO_RANDOM_AT_START
- if(modem_speed < 9600) /* if modem_speed is 0-9599, then show */
- { /* the low modem speed chat screen */
- char temp[201]; /* called '2400.ANS', if it doens't */
- /* exist, then go get one like normal */
- sprintf(temp, "%s2400.ANS", achat_dir);
- if(exist(temp))
- pick_file = -1; /* set low modem speed flag */
- }
- #endif
-
-
- /* This while loop is present so that we can set chat_done = true, but */
- /* not turn off chatting, this will free up current memory and reload */
- /* a new chat menu */
- while(chatting && !hangup)
- {
-
- chat_done = 0; /* in case it gets turned off, */
- /* like what happens when you want */
- /* a new chat menu set loaded */
- if(pick_file < 0)
- {
- strcpy(fname, "2400.ANS");
- pick_file = 0;
- }
- else if(pick_file > 0)
- {
- pick_file = 0;
- if(!select_achat_filename(fname))
- return;
- }
- else if(!get_achat_filename(fname)) /* Pick a random screen to chat in */
- return;
-
- if(!achat_read_config(fname))
- return; /* Read the INI file to define it */
-
- display_achat_screen(fname, sysop_name); /* print the screen */
-
- if(us_x > 0 && us_y > 0)
- {
- GOTO_XY(us_x, us_y);
- setc(us_c);
- strcpy(temp,thisuser.name); /* move this out of the #ifdef in*/
- properize(temp); /* newuser.c if you have probs */
- outstr(temp); /* sysop name */
- }
- if(sy_x > 0 && sy_y > 0)
- {
- GOTO_XY(sy_x, sy_y);
- setc(sy_c);
- strcpy(temp,sysop_name); /* move from #ifdef in */
- properize(temp); /* newuser.c if you have probs */
- outstr(temp); /* the users name */
- }
-
-
- sys_line = sys_pos = 0; /* Set up a few global variables */
- user_line = user_pos = 0;
-
- go_do_achat(); /* And run the chat program */
-
- if(sys_lines) free(sys_lines); /* free memory if it was allocated */
- if(user_lines) free(user_lines);
- if(sys_text) free(sys_text);
- if(user_text) free(user_text);
- }
-
- topdata=save_topdata;
- topscreen();
- }
-
-
- void go_do_achat(void)
- {
- int key;
- unsigned long counter = 0;
-
- chatting = 3;
-
- GOTO_XY(sys_lines[0].xpos + sys_pos, sys_lines[0].ypos); /* set cursor up */
-
- if(welcome_text[0]) /* display welcome message */
- {
- display_achat_string(welcome_text, 1);
- display_achat_string("\n\n", 1);
- }
-
- while(!chat_done && chatting && !hangup)
- {
- if(counter % 10 == 0) /* every 10 key strokes, update */
- { /* then time on and time left */
- if(to_x > 0 && to_y > 0)
- {
- SaveCursor(); /* Save the cursor position */
- GOTO_XY(to_x, to_y); /* reposition it for writting */
- setc(time_on_color); /* the amount of time on */
- outstr(ctim(timer() - timeon)); /* How long user has been on */
- RecallCursor(); /* and restore the cursor pos */
- }
- if(tl_x > 0 && tl_y > 0)
- {
- SaveCursor(); /* Save our cursor position, */
- GOTO_XY(tl_x, tl_y); /* set it for writting the time */
- setc(time_left_color); /* left for this logon */
- outstr(ctim(nsl())); /* How much time the user has */
- RecallCursor(); /* Put cursor back where it was */
- }
- }
- ++counter; /* amount of keys processed */
-
-
- key = getkey(); /* Add the key to our screen. */
- add_achat_key(key, flip_sides ? !lastcon : lastcon);
- /* lastcon is a variable which */
- } /* is set to 1 if the last key */
- outchr(12); /* was made by the local user */
- } /* and 0 for remote user */
-
-
-
- char *achat_fix_fname(char *fname)
- {
- char *tmp;
-
- if(fname) /* Just a saftey check */
- {
- tmp = strchr(fname, '.'); /* see if a dot exists */
- if(!tmp) /* if not */
- strcat(fname, ".INI"); /* append a .INI */
- else /* otherwise starting at */
- strcpy(tmp, ".INI"); /* the '.', copy .INI to it */
- }
- return(fname);
- }
-
- int achat_read_config(char *fname)
- {
- char ini_pn[201];
- ini_record *ini_info;
- char temp[201], tmp_line[50];
- int x, temp_number[10];
-
-
- tl_x = tl_y = to_x = to_y = -1; /* default to no time on and t.left */
- us_x = us_y = sy_x = sy_y = -1; /* default to no sysop or user name */
- time_on_color = time_left_color = 7;
- us_c = sy_c = 7;
- sys_bk_color = user_bk_color = -1; /* default to random color is off */
- sys_rand_freq=user_rand_freq = -1; /* default to random color is off */
- sys_rand_color_set = 0; /* blue color set */
- user_rand_color_set = 0; /* blue color set */
-
- strcpy(temp, fname); /* don't change our orig fname */
- achat_fix_fname(temp); /* make sure extension is .INI */
-
-
- /* all Asylum Chat stuff is located in a directory called ACHAT off of */
- /* your gfiles directory */
- sprintf(ini_pn, "%s%s", achat_dir, temp);
-
- if((ini_info = open_ini(ini_pn, IF_OREAD)) == NULL) /* try to open INI file */
- {
- pl("Can't open INI file for ACHAT"); /* Printed out for sysop to see */
- pausescr();
- return 0;
- }
-
- /*-----------------------------------------------------------------*/
- /* Welcome text is text that is first displayed on entry of the */
- /* chat screen */
-
- ini_read_string(ini_info, "Sysop", "Welcome", welcome_text);
-
-
- /*-----------------------------------------------------------------*/
- /* Time on - shows the amount of time the user has left on the bbs */
- /* this time is updated every 10 key strokes, and only shown if */
- /* the to_x has a value greater than -1 */
-
- if(ini_read_string(ini_info, "Macros", "Time On", temp))
- achat_get_3_fields(temp, &to_x, &to_y, &time_on_color);
-
-
- /*-----------------------------------------------------------------*/
- /* Time left - Alot like time on, but shows how much time is left */
- /* on the board... it is only shown if coordinates greater than -1 */
- /* are given */
-
- if(ini_read_string(ini_info, "Macros", "Time Left", temp))
- achat_get_3_fields(temp, &tl_x, &tl_y, &time_left_color);
-
-
- /*-----------------------------------------------------------------*/
- /* An alternate the the $> and $<, you can specify the User and */
- /* sysop name positions and color in the .INI file */
- if(ini_read_string(ini_info, "Macros", "User Name", temp))
- achat_get_3_fields(temp, &us_x, &us_y, &us_c);
-
- if(ini_read_string(ini_info, "Macros", "Sysop Name", temp))
- achat_get_3_fields(temp, &sy_x, &sy_y, &sy_c);
-
-
-
- /* Find out how many lines are setup for this screen on the sysop side */
- amount_sys_lines = ini_read_number(ini_info, "SYSOP", "Amount of Lines");
-
- if(!amount_sys_lines)
- { sysoplog("Err-NSL"); close_ini(ini_info); return 0; }
-
-
- /* find out if there is a user side or not... if not, it will be like */
- /* chatting in the stock non-two way chat, but you still have an ansi */
- no_user_side = ini_read_boolean(ini_info, "SYSOP", "No user side");
-
-
- /* Find out how many lines are setup for this screen on the user side */
- amount_user_lines = ini_read_number(ini_info, "USER", "Amount of Lines");
-
- if(!amount_user_lines && no_user_side==0)
- { sysoplog("Err-NUL"); close_ini(ini_info); return 0; }
-
-
- sys_lines = (lines_record *)malloc(amount_sys_lines * sizeof(lines_record));
- user_lines = (lines_record *)malloc(amount_user_lines * sizeof(lines_record));
-
- sys_text = (char *)malloc(amount_sys_lines * ACHAT_MAX_WIDTH);
- user_text = (char *)malloc(amount_user_lines * ACHAT_MAX_WIDTH);
-
- memset(sys_text, 0, amount_sys_lines * ACHAT_MAX_WIDTH);
- memset(user_text, 0, amount_user_lines * ACHAT_MAX_WIDTH);
-
-
- /* Check to see if any thing was unable to get memory */
- if(!sys_lines || !sys_text)
- {
- sysoplog("Err-NM"); /* The memory is free'd at the end of */
- /* function 'achat' */
-
- close_ini(ini_info);
- return 0;
- }
-
-
-
- /*---------------------------------------------------------------------*/
- /* Check to see if any thing was unable to get memory */
- /* the absense of user_text or user_lines is only fatal if there is */
- /* in fact a user side. We obviously don't need memory allocated */
- /* or lines specified for a user side if there isn't one present */
-
- if(no_user_side == 0) /* see if there is a user side */
- {
- if(!user_lines || !user_text) /* if so, there better be both */
- { /* lines and memory, else fail */
- sysoplog("Err-NM"); /* The memory is free'd at the */
- /* end of function 'achat' */
-
- close_ini(ini_info); /* release ini info stuff */
- return 0; /* and return with failure */
- }
- }
-
-
-
-
- /*---------------------------------------------------------------------*/
- /* loop through all the line and read in the line information */
- /* for the sysop side of the screen */
-
-
- for(x = 1; x <= amount_sys_lines; ++x)
- {
- sprintf(tmp_line, "Line %d", x);
- sprintf(temp, "1, %d, 80", x);
- ini_read_string(ini_info, "SYSOP", tmp_line, temp);
-
- if(!parse_achat_line_info(temp, &sys_lines[x-1]))
- {
- sprintf(temp, "Check '%s' in %s in the [SYSOP] section", tmp_line, fname);
- sysoplog(temp);
- outstr(temp);
- pausescr();
- }
- }
-
-
-
-
- /*---------------------------------------------------------------------*/
- /* Parse through all the lines and read in the line information */
- /* For the users side of the screen */
-
- for(x = 1; x <= amount_user_lines; ++x)
- {
- sprintf(tmp_line, "Line %d", x);
- sprintf(temp, "1, %d, 80", x);
- ini_read_string(ini_info, "USER", tmp_line, temp);
-
- if(!parse_achat_line_info(temp, &user_lines[x-1]))
- {
- sprintf(temp, "Check '%s' in %s in the [USER] section", tmp_line, fname);
- sysoplog(temp);
- outstr(temp);
- pausescr();
- }
- }
-
-
-
- /* -------------------------------------------------------------------- */
- /* Read sysop color options ... */
- /* */
- /* You can have 2 different (almost 3) types of colors: */
- /* Defined colors for upper/lower/digits */
- /* Rotating colors */
- /* You can have a modified rotating colors which rotates every word */
- /* change */
- /* Rotating colors can be 1 or 5 types, rotates through blue, red, */
- /* gray, brown or all colors */
-
- if(ini_read_boolean(ini_info, "SYSOP", "Random Colors"))
- {
-
- strcpy(temp, "0,3"); /* Bg color is 0 and rotate every 3 chars */
-
- ini_read_string(ini_info, "SYSOP", "Random Options", temp);
- achat_get_fields(temp, temp_number, 2);
- sys_bk_color = temp_number[0];
- sys_rand_freq = temp_number[1];
-
- if(sys_bk_color > 15) /* make bk color a 0-7 color */
- sys_bk_color = sys_bk_color >> 4;
-
-
- sys_bk_color &= 7; /* mask out blink or anything else */
-
-
- strcpy(temp, "BLUE");
- ini_read_string(ini_info, "SYSOP", "Random Color Set", temp);
- if(strcmpi(temp, "BLUE")==0)
- sys_rand_color_set = 0;
- else if(strcmpi(temp, "RED")==0)
- sys_rand_color_set = 1;
- else if(strcmpi(temp, "GRAY")==0)
- sys_rand_color_set = 2;
- else if(strcmpi(temp, "BROWN")==0)
- sys_rand_color_set = 3;
- else if(strcmpi(temp, "ALL")==0)
- sys_rand_color_set = 4;
-
- sys_cur_color = colors[sys_rand_color_set].colors[0];
- } /* allow sys_other_colors to still read, just in case error here */
-
-
-
-
-
- /*----------------------------------------------------------------------*/
- /* These are the colors that will be used for the sysops side */
- /* looking at the names, uppercase, lowercase and anything left */
- /* over can have there own uniq colors */
-
- sys_upper_color = ini_read_number(ini_info,"SYSOP","Uppercase Color");
- sys_lower_color = ini_read_number(ini_info,"SYSOP","Lowercase Color");
- sys_numeric_color = ini_read_number(ini_info,"SYSOP","Numeric Color");
-
-
-
-
-
- /* -------------------------------------------------------------------- */
- /* Read user color options ... */
- /* */
- /* You can have 2 different (almost 3) types of colors: */
- /* Defined colors for upper/lower/digits */
- /* Rotating colors */
- /* You can have a modified rotating colors which rotates every word */
- /* change */
-
-
- if(ini_read_boolean(ini_info, "USER", "Random Colors"))
- {
- strcpy(temp, "0,3"); /* Back color is 0 and rotate every 3 chars */
- ini_read_string(ini_info, "USER", "Random Options", temp);
- achat_get_fields(temp, temp_number, 2);
- user_bk_color = temp_number[0];
- user_rand_freq = temp_number[1];
-
- if(user_bk_color > 15) /* make bk color a 0-7 color */
- user_bk_color = user_bk_color >> 4;
-
- user_bk_color &= 7; /* mask out blink or anything else */
-
- strcpy(temp, "BLUE");
- ini_read_string(ini_info, "USER", "Random Color Set", temp);
- if(strcmpi(temp, "BLUE")==0)
- user_rand_color_set = 0;
- else if(strcmpi(temp, "RED")==0)
- user_rand_color_set = 1;
- else if(strcmpi(temp, "GRAY")==0)
- user_rand_color_set = 2;
- else if(strcmpi(temp, "BROWN")==0)
- user_rand_color_set = 3;
- else if(strcmpi(temp, "ALL")==0)
- user_rand_color_set = 4;
-
- user_cur_color = colors[user_rand_color_set].colors[0];
- } /* allow user_other_colors to still read, just in case error here */
-
-
- /* these are the colors that will be used for the user side */
- user_upper_color = ini_read_number(ini_info, "USER", "Uppercase Color");
- user_lower_color = ini_read_number(ini_info, "USER", "Lowercase Color");
- user_numeric_color = ini_read_number(ini_info, "USER", "Numeric Color");
-
-
-
-
-
- /*------------------------------------------------------------------------*/
- /* Alt Clear Screen - If true, will use the WWIV style wrapping, where it */
- /* pulls the bottom 3 lines up to the top. */
- /* You must be careful that your screen can properly support this though */
- /* If turned off, it will do a Wildcat style, where it clears 2 lines */
- /* below the line you are on at a time, leaving the rest of the screen */
- /* untouched. */
-
- alt_achat_clear = ini_read_boolean(ini_info, "SYSOP", "Alt Clear Screen");
-
- close_ini(ini_info);
-
-
- return 1;
- }
-
- int achat_get_3_fields(char *line, int *one, int *two, int *three)
- {
- int fields[3];
-
- if(achat_get_fields(line, fields, 3) != 3)
- return 0;
-
- *one=fields[0];
- *two=fields[1];
- *three=fields[2];
-
- return 1;
- }
-
-
- int achat_get_fields(char *line , int *fields, int max)
- {
- char *p;
- int amount = 0;
-
- p=strtok(line, ",");
- while(p && amount < max)
- {
- fields[amount++]=atoi(p);
- p=strtok(NULL, ",");
- }
- return(amount); /* return the amount of fields done */
- }
-
-
- int parse_achat_line_info(char *line, void *destin)
- {
- char *tmp, *tmp1;
- lines_record *dest;
- int fields[3];
-
- dest = (lines_record *) destin; /* so that I don't have to put struct */
- /* lines_record in vardec.h */
-
- if(achat_get_fields(line, fields, 3) != 3)
- return 0; /* we need 3 numbers, if we don't get */
- /* them, return with failure */
-
- dest->xpos = fields[0];
- dest->ypos = fields[1];
- dest->length= fields[2];
-
- return 1; /* success */
- }
-
-
-
- /* This function will pull up a random chat file, it will search through */
- /* a directory called 'ACHAT' off of your gfiles directory. It will find */
- /* out how many files are there, then pick one randomly */
- char *get_achat_filename(char *fname)
- {
- struct ffblk ff;
- char file[201];
- int amount = 0, cur;
- int done = 0;
-
- sprintf(file, "%s*.ANS", achat_dir); /* Wildcard search */
-
- done = findfirst(file, &ff, 0); /* Find first match */
-
- if(done != 0) /* if one was found... */
- ++amount; /* increment amount found */
-
- while(!done) /* loop through, finding */
- { /* all matches */
- done = findnext(&ff);
- ++amount; /* keep track of amount found */
- }
-
- if(!amount) /* if none were found.. */
- { sysoplog("Err-NoANS"); return NULL; } /* tell and return */
-
- amount = rand() % amount; /* pick one radomly */
-
- cur = 0;
- done = findfirst(file, &ff, 0); /* Then do a findfirst/ */
- while(!done && cur != amount) /* findnext that many times */
- { /* and that will be our */
- done = findnext(&ff); /* random file */
- ++cur;
- }
-
- strcpy(fname, ff.ff_name); /* copy the found filename */
- return(fname); /* and return it */
- }
-
-
-
- /* This file will print out our ansi menu without being able to be aborted */
- /* It will also intercept two macros, one '$<' for sysop's name, and the */
- /* other $> for the user name. */
- int printfile_na(char *fn, char *sysop_name)
- {
-
- char *ss, s2[201], prop_name[101];
- long pos, len;
- int i, ch;
-
- pos=0;
-
- if(exist(fn)) /* First see if the full pathname is specified */
- strcpy(s2, fn); /* if so, just copy it to s2 */
- else
- {
- sprintf(s2,"%s%s", languagedir,fn); /* no? try the language dir */
- if(!exist(fn))
- sprintf(s2,"%s%s",syscfg.gfilesdir,fn); /* still no, try gfiles dir */
- }
-
- CLS();
- ss=get_file(s2,&len); /* Read the file into memory */
- if (ss!=NULL) /* if it was read.... */
- {
- pos = 0; /* starting from the begining */
- while(pos < len && !hangup) /* read through all bytes of the */
- { /* file, displaying them one at */
- lines_listed = 0; /* keep pause away */
-
- if(ss[pos] == '$') /* possible macro */
- {
- if(ss[pos+1] == '<') /* less than sign means show the */
- {
- SaveCursor(); /* Save our current position */
- strcpy(prop_name,sysop_name);/* move this out of the #ifdef in*/
- properize(prop_name); /* newuser.c if you have probs */
- outstr(prop_name); /* sysop name */
- RecallCursor(); /* go back to original position */
- CURSORRIGHT(2); /* and fool the ansi to think */
- /* only 2 chars were printed */
- pos+=2; /* inc pos by two */
- continue; /* and jump back to 'while' */
- }
- if(ss[pos+1] == '>') /* greater than sign mean show */
- {
- SaveCursor();
- strcpy(prop_name,thisuser.name); /* move from #ifdef in */
- properize(prop_name); /* newuser.c if you have probs */
- outstr(prop_name); /* the users name */
- RecallCursor(); /* go back to original position */
- CURSORRIGHT(2); /* and fool the ansi to think */
- /* only 2 chars were printed */
- pos+=2; /* increment the pos by 2 and */
- continue; /* jump up to the while loop */
- }
- if(ss[pos+1] == ',') /* less than sign means show the */
- {
- tl_x = WhereX()+1; /* where to position the time */
- tl_y = WhereY()+1; /* left when doing updates */
- SaveCursor(); /* Save our current position */
- outstr(ctim(nsl())); /* Time left */
- RecallCursor(); /* go back to original position */
- CURSORRIGHT(2); /* and fool the ansi to think */
- /* only 2 chars were printed */
- pos+=2; /* inc pos by two */
- continue; /* and jump back to 'while' */
- }
- if(ss[pos+1] == '.') /* greater than sign mean show */
- {
- to_x = WhereX()+1; /* where to position the time */
- to_y = WhereY()+1; /* left when doing updates */
-
- SaveCursor();
- outstr(ctim(timer()-timeon));/* Time on */
- RecallCursor(); /* go back to original position */
- CURSORRIGHT(2); /* and fool the ansi to think */
- /* only 2 chars were printed */
- pos+=2; /* increment the pos by 2 and */
- continue; /* jump up to the while loop */
- }
- } /* End of if possible macro */
-
- outchr(ss[pos++]); /* display non macro character */
-
- if(!empty() && lastcon) /* allow SYSOP (only) to abort */
- { /* the display */
- ch=inkey(); /* get key, if one is waiting */
- if(ch==' ') /* if it is a space, then break */
- break; /* out of our while loop */
- }
- }
-
- free(ss); /* free up our memory that was */
- return(1); /* allocated by get_file */
- }
- else
- return(0); /* file was not printed */
- }
-
-
-
- void SaveCursor(void)
- { /* ansi sequence to save the */
- outstr("\033[s"); /* cursor position, so that it */
- } /* may be moved and restored */
-
- void RecallCursor(void)
- { /* ansi sequence to recall the */
- outstr("\033[u"); /* cursor position from a */
- } /* previous SaveCursor */
-
-
- void display_achat_screen(char *fname, char *sysop_name)
- {
- char fn[201];
-
- CLS(); /* clear the screen */
- sprintf(fn, "%s%s", achat_dir, fname); /* point to ansi */
- printfile_na(fn, sysop_name); /* and print it out */
- }
-
-
-
-
-
-
- void display_achat_char(int c, int sysop)
- {
- static int sys_counter=0, user_counter=0;
- int color;
-
- if(sysop && sys_rand_freq > 0)
- {
- ++sys_counter;
-
- if((sys_rand_freq != 32 && sys_counter % sys_rand_freq == 0) ||
- (sys_rand_freq == 32 && c == 32))
- {
- ++sys_cur_color;
-
- if(sys_cur_color > colors[sys_rand_color_set].amount_colors)
- sys_cur_color = 0;
-
- }
- color = colors[sys_rand_color_set].colors[sys_cur_color];
- if(color == sys_bk_color)
- ++color;
- setc(color + (sys_bk_color <<4));
- }
- else if(!sysop && user_rand_freq > 0)
- {
- ++user_counter;
-
- if((user_rand_freq != 32 && user_counter % user_rand_freq == 0) ||
- (user_rand_freq == 32 && c == 32))
- {
- ++user_cur_color;
- if(user_cur_color > colors[user_rand_color_set].amount_colors)
- user_cur_color = 0;
- }
- color = colors[user_rand_color_set].colors[user_cur_color];
- if(color == user_bk_color)
- ++color;
- setc(color + (user_bk_color << 4));
- }
- else
- {
- if(islower(c)) /* use lower color for lower case keys */
- setc(sysop > 0 ? sys_lower_color : user_lower_color);
- else if(isupper(c)) /* use upper color for upper case keys */
- setc(sysop > 0? sys_upper_color : user_upper_color);
- else /* use numeric color for all other keys */
- setc(sysop > 0 ? sys_numeric_color : user_numeric_color);
- }
- outchr(c);
- }
-
-
- /* This function displays a null terminated string. It is called by */
- /* function 'add_achat_key', but if you notice, to print each key, it */
- /* turns around and calls 'add_achat_key', this is so it properly */
- /* handles any wrapping that my need to be done, as well as any other */
- /* special keys that are handled in that function, as opposed to */
- /* directly printing them out to the screen. */
- void display_achat_string(char *s, int sysop)
- {
- while(*s)
- add_achat_key(*s++, sysop);
- }
-
-
-
- /* This function clears the entire typeable area for either the sysop or */
- /* user, depending on what is specified */
- void clear_achat_type_area(int sysop)
- {
- int x = 0, xpos, ypos, length;
- int amount = sysop ? amount_sys_lines : amount_user_lines;
-
- while(x < amount) /* loop through all the lines */
- {
- if(sysop) /* get the x, y and length */
- { /* depending on if it is the */
- xpos = sys_lines[x].xpos; /* sysop or user side we are */
- ypos = sys_lines[x].ypos; /* erasing */
- length = sys_lines[x].length;
- }
- else
- {
- xpos = user_lines[x].xpos;
- ypos = user_lines[x].ypos;
- length = user_lines[x].length;
- }
- /* use the lower color as the erase color */
- setc(sysop ? sys_lower_color : user_lower_color);
- GOTO_XY(xpos, ypos); /* set to first postion */
-
- repeat_char(' ', length-1); /* and display 'length-1' spaces */
- ++x;
-
- }
- }
-
-
- void wwiv_style_wrap_up(int sysop)
- {
- int amount = sysop ? amount_sys_lines : amount_user_lines, x;
- char *this_text = sysop ? sys_text : user_text, *t;
-
-
- /* clear out all typeable area for sysop or user */
- clear_achat_type_area(sysop);
-
- /* if we are trying to wrap more than the amount of lines we */
- /* have to use + 2, then don't wrap anything up at all */
- if(amount + 2 < AMOUNT_TO_WRAP_UP)
- return;
-
- if(sysop)
- { sys_pos = 0; sys_line = 0; }
- else
- { user_pos = 0; user_line = 0; }
-
- for(x=0; x < AMOUNT_TO_WRAP_UP; x++)
- {
- t = this_text+((amount-AMOUNT_TO_WRAP_UP+x)*ACHAT_MAX_WIDTH);
- if(t[0] != 13) /* don't display empty line */
- display_achat_string(t, sysop);
- }
- }
-
-
- /* This function is like the above, but instead of clearing the whole */
- /* screen, it will only clear the next two lines on either the sysop or */
- /* user side */
- void clear_achat_next_two_lines(int sysop)
- {
- int x, y, xpos, ypos, length;
- int amount = sysop ? amount_sys_lines : amount_user_lines;
-
- if(alt_achat_clear) /* if you have the alternate clear option */
- return;
-
- for(x = 1; x <= 2; x++) /* loop twice */
- {
-
- y = sysop ? sys_line + x : user_line + x; /* figure out what the next line is */
- if(y >= amount) /* see if we wrapped back up to the */
- y -= amount; /* top of the screen */
-
- if(sysop)
- {
- xpos = sys_lines[y].xpos;
- ypos = sys_lines[y].ypos;
- length = sys_lines[y].length;
- sys_pos = 0;
- }
- else
- {
- xpos = user_lines[y].xpos;
- ypos = user_lines[y].ypos;
- length = user_lines[y].length;
- user_pos = 0;
- }
- setc(sysop ? sys_lower_color : user_lower_color);
- GOTO_XY(xpos, ypos);
-
- repeat_char(' ', length-1); /* display 'lenght-1' spaces to clear line */
- }
- }
-
-
-
-
-
- void add_achat_key(int key, int sysop)
- {
- lines_record *this_lines;
- int this_pos, this_line, this_amount;
- char temp[50];
- char *this_text;
-
-
- if(no_user_side) /* if we don't have a user side, then get the specs */
- if(!sysop) /* from the sysop definition, but set it so we know */
- sysop = -1; /* it is the user so we can use the user color still */
-
-
- this_lines = sysop ? &sys_lines[sys_line] : &user_lines[user_line];
- this_line = sysop ? sys_line : user_line;
- this_pos = sysop ? sys_pos : user_pos;
- this_amount = sysop ? amount_sys_lines : amount_user_lines;
- this_text = sysop ? sys_text + (this_line * ACHAT_MAX_WIDTH) :
- user_text + (this_line * ACHAT_MAX_WIDTH);
-
- switch(key)
- {
- case 18: /* ^R to load a new menu set */
- if(lastcon) /* only the sysop can reload the */
- {
- chat_done = 1; /* menus */
- return;
- }
- break;
-
- case 26: /* ^Z to flip sides */
- if(lastcon)
- {
- flip_sides = !flip_sides;
- return;
- }
- break;
-
- case 14: /* ^N load a chat screen by name */
- if(lastcon)
- {
- chat_done = 1;
- pick_file = 1;
- return;
- }
-
-
- case 3: /* color codes */
- return; /* don't want any */
-
- case 8: /* backspace */
- if(this_pos) /* if we aren't up against left wall */
- {
- GOTO_XY(this_lines[0].xpos+(sysop ? sys_pos : user_pos), this_lines[0].ypos);
- setc(sysop ? sys_lower_color : user_lower_color);
-
- if(sysop) /* decrement position */
- --sys_pos;
- else
- --user_pos;
-
- backspace(); /* and erase previous character */
- }
- return;
-
- case 13: /* carriage return */
- case 10: /* line feed */
- this_text[this_pos++] = key; /* put key in our buffer */
- this_text[this_pos] = 0; /* keep buffer null terminated */
-
- if(!alt_achat_clear) /* if you have the alt clear opt */
- clear_achat_next_two_lines(sysop);/* then clear next two lines */
- else if(this_line >= this_amount-1)
- {
- wwiv_style_wrap_up(sysop); /* else if we need to go to the top,*/
- return; /* then clear the whole thing */
- }
- if(this_line < this_amount-1) /* if we don't need to wrap back up */
- { /* to the top... */
- if(sysop)
- { ++sys_line; sys_pos = 0; } /* increment line and set pos to 0 */
- else
- { ++user_line; user_pos = 0; }
-
- GOTO_XY(this_lines[1].xpos, this_lines[1].ypos);
- return;
- }
-
- if(sysop) /* if we do need to jump back up to the top... */
- { sys_line = 0; GOTO_XY(sys_lines[0].xpos, sys_lines[0].ypos); }
- else
- { user_line = 0; GOTO_XY(user_lines[0].xpos, user_lines[0].ypos); }
-
- return;
-
- case 7: /* Bell ^G */
- outcomch(7);
- return;
-
- case 23: /* ^W delete word */
- if(this_pos)
- {
- GOTO_XY(this_lines[0].xpos+(sysop ? sys_pos : user_pos), this_lines[0].ypos);
- setc(sysop ? sys_lower_color : user_lower_color);
-
- --this_pos;
- while(isspace(this_text[this_pos]) && this_pos > -1)
- { --this_pos; backspace(); }
-
- if(this_pos < 0)
- this_pos = 0;
-
- while(!(isspace(this_text[this_pos])) && this_pos > -1)
- { --this_pos; backspace(); }
-
- if(this_pos < 0)
- this_pos = 0;
-
- if(sysop)
- sys_pos = this_pos;
- else
- user_pos = this_pos;
-
- this_text[this_pos] = 0;
- }
- return;
-
-
- case 24: /* ^X erase line */
- if(this_pos)
- {
- GOTO_XY(this_lines[0].xpos+(sysop ? sys_pos : user_pos), this_lines[0].ypos);
- setc(sysop ? sys_lower_color : user_lower_color);
-
- if(sysop) /* set position back to 0 */
- sys_pos=0;
- else
- user_pos=0;
-
- while(this_pos)
- { backspace(); --this_pos; }
-
- this_text[0] = 0;
-
- }
- return;
-
- case 9: /* tab, just display 4 spaces */
- display_achat_string(" ", sysop);
- return;
-
-
- default:
- if(key < 32) /* kill non printable characters */
- return;
- break;
- }
-
-
-
- if(this_pos >= this_lines->length-1) /* if we need word wrap to the next */
- { /* line on the screen */
- int wrap, x = 0, y, marker;
- int save_wrap_pos;
-
-
- if(!alt_achat_clear) /* if you have the alt clear */
- clear_achat_next_two_lines(sysop);/* option, then clear next two lines */
- else if(this_line >= this_amount-1)
- wwiv_style_wrap_up(sysop); /* else if we need to go to the top, */
- /* then clear the whole thing */
-
-
- /* Re-read these values since they may change with the wwiv style */
- /* wrapping the text up and all... */
- this_lines = sysop ? &sys_lines[sys_line] : &user_lines[user_line];
- this_line = sysop ? sys_line : user_line;
- this_pos = sysop ? sys_pos : user_pos;
- this_amount = sysop ? amount_sys_lines : amount_user_lines;
- this_text = sysop ? sys_text + (this_line * ACHAT_MAX_WIDTH) :
- user_text + (this_line * ACHAT_MAX_WIDTH);
-
-
-
- /* determin the amount of characters we are going to wrap. I have it */
- /* setup to wrap a 25% of the size of the current line */
- wrap = this_lines->length / 4;
-
-
-
- /* put cursor right past last character, so that we can, one by one, */
- /* delete them as we count backwards */
- GOTO_XY(this_lines->xpos + this_pos, this_lines->ypos);
- y=this_pos; /* set a marker, so that we know what or original pos is */
- --this_pos; /* decrement one to get off of the null which I keep here */
- while(!isspace(this_text[this_pos]) && x < wrap)
- { /* loop back until we find a space (or x >= wrap */
- ++x;
- --this_pos;
- backspace(); /* erase those characters */
- }
-
-
-
- /* save our point of wrap, so that once we get done putting the text */
- /* to be wrapped in a string to be displayed on the next line, we */
- /* will put a space at this position and terminate our chat line */
- save_wrap_pos = this_pos;
-
- /* Now, we know how many characters we removed from the screen, put */
- /* those in our temp string so that we can later display them on our */
- /* next line */
- ++this_pos; /* get off of the white space we just found */
- x = 0;
- while(this_pos < y)
- {
- temp[x] = this_text[this_pos];
- ++this_pos;
- ++x;
- }
- temp[x++] = key; /* add the key we just entered */
- temp[x] = 0; /* you know it has to be terminated */
-
-
- /* set a SPACE/NULL at this point of wrapping... this will kill */
- /* a character if we wrapped in the middle of a word, but I am going */
- /* to chat this as not an often happening, and when it does, it wont */
- /* be noticed... but who knows what will have to be done later.... */
- this_text[save_wrap_pos] = ' ';
- this_text[save_wrap_pos+1] = 0;
-
-
-
- if(this_line >= this_amount-1) /* if we need to wrap back */
- { /* up to the top, copy the */
- strcpy(sysop ? sys_text : user_text, temp);/* text to the front of the */
- if(sysop) /* text screen */
- sys_line = 0; /* set line # to 0 */
- else
- user_line = 0;
- }
- else /* if we are just going to */
- { /* the next line */
- strcpy(this_text+(ACHAT_MAX_WIDTH), temp); /* copy text into the corct */
- if(sysop) /* spot and then */
- ++sys_line; /* increment line # by 1 */
- else
- ++user_line;
- }
-
- if(sysop) /* anyway, since we wrapped */
- sys_pos = 0; /* to the next line, our */
- else /* 'x' position is now 0 */
- user_pos = 0;
-
-
- display_achat_string(temp, sysop); /* display our temp string */
- return; /* on the next line */
-
- }
-
- /* if we get here, we are not wrapping, just displaying the key */
-
- /* set cursor to correct position */
- GOTO_XY(this_lines->xpos + this_pos, this_lines->ypos);
- display_achat_char(key, sysop); /* and display char with correct color */
-
- this_text[this_pos++] = key; /* put key in our buffer */
- this_text[this_pos] = 0; /* keep buffer null terminated */
-
- if(sysop) /* increment position by one */
- ++sys_pos;
- else
- ++user_pos;
-
- return;
- }
-
-
- /* Mostly written by Swordfish, thanks everyone for all the help you give me */
- char *select_achat_filename(char *fname)
- {
- struct ffblk ff;
- char file[101];
- int amount = 0, cur;
- int done = 0;
- int fli,x,ru;
- char s[80];
-
-
-
- sprintf(file, "%s*.ANS", achat_dir); /* Wildcard search */
- done = findfirst(file, &ff, 0); /* Find first match */
-
- if(!done) /* if one was found... */
- ++amount; /* increment amount found */
-
- while(done != 0) /* loop through, finding */
- { /* all matches */
- done = findnext(&ff);
- ++amount; /* keep track of amount found */
- }
-
- if(!amount) /* if none were found.. */
- { sysoplog("Err-NoANS"); return NULL; } /* tell and return */
-
- curatr=WHITE;
- pr_Wait(1);
- movecsr(31, 1);
- show_achat_screens();
-
- welldone:
- savescreen(&screensave);
- strcpy(s,"1");
- curatr=YELLOW+(BLUE<<4);
- makewindow(20,0,43,3);
- movecsr(22,1);
- outs("Choose:");
- movecsr(31,1);
- outs(charstr(30,32));
- movecsr(31,1);
- editline(s,30,ALL,&ru,s);
-
-
- if (s[0]=='?') {
- show_achat_screens();
- goto welldone;
- }
-
- curatr=YELLOW;
- fli=atoi(s)-1;
- cur = 0;
- done = findfirst(file, &ff, 0);
- while(!done && cur != fli)
- {
- done = findnext(&ff);
- ++cur;
- }
- strcpy(fname, ff.ff_name);
- return(fname);
- }
-
- void show_achat_screens(void)
- {
- struct ffblk ff;
- char finfo[101], file[101], desc[101];
- int done, amount = 1;
-
- curatr=WHITE;
- sprintf(file, "%s*.ANS", achat_dir); /* Wildcard search */
- done = findfirst(file, &ff, 0); /* Find first match */
-
- outs("\r\n\r\n\r\n");
- open_achat_descriptions();
- while(!done) /* loop through, finding */
- { /* all matches */
- get_achat_description(ff.ff_name, desc);
- sprintf(finfo, "%2d) %-12.12s %2ldk %s\r\n", amount++, ff.ff_name, ff.ff_fsize > 1023 ? ff.ff_fsize / 1024L : 1L, desc);
- outs(finfo);
- done = findnext(&ff);
- }
- close_achat_descriptions();
- outs("\r\n");
- }
-
-
- void open_achat_descriptions(void)
- {
- char fname[151];
- sprintf(fname, "%sDESCRIPT.ION", achat_dir);
- achat_desc=fopen(fname, "r");
-
- if(!achat_desc)
- {
- sprintf(fname, "%sFILES.BBS", achat_dir);
- achat_desc=fopen(fname, "r");
- }
- }
-
- void close_achat_descriptions(void)
- {
- if(achat_desc)
- fclose(achat_desc);
- }
-
-
- char *get_achat_description(char *name, char *desc)
- {
- char temp[201], *tmp;
- int x;
-
-
- if(!achat_desc)
- { *desc=0; return NULL; }
-
-
- fseek(achat_desc, 0, SEEK_SET);
-
-
- while(1)
- {
- if(!fgets(temp, 200, achat_desc))
- { *desc=0; return NULL; }
-
- tmp = strchr(temp, ' ');
- if(!tmp)
- continue;
-
- tmp[0] = 0;
- ++tmp;
-
- if(strcmpi(name, temp) == 0)
- {
-
- strcpy(desc, tmp);
- x = strlen(desc);
- --x;
-
- if(x > 55)
- { x = 54; desc[x+1] = 0; }
-
-
- if(x >= 0 && isspace(desc[x]))
- {
- while(x > 0 && isspace(desc[x]))
- --x;
- if(!isspace(desc[x]))
- ++x;
- desc[x] = 0;
- }
- return(desc);
- }
- }
- }
-
-
-
-