|
|
1.1 root 1: #line 1 "CON_HI.C"
2:
3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
4:
5: #include "sbbs.h"
6:
7: extern char question[128];
8:
9: char *mnestr;
10:
11: /****************************************************************************/
12: /* Waits for remote or local user to input a CR terminated string. 'length' */
13: /* is the maximum number of characters that getstr will allow the user to */
14: /* input into the string. 'mode' specifies upper case characters are echoed */
15: /* or wordwrap or if in message input (^A sequences allowed). ^W backspaces */
16: /* a word, ^X backspaces a line, ^Gs, BSs, TABs are processed, LFs ignored. */
17: /* ^N non-destructive BS, ^V center line. Valid keys are echoed. */
18: /****************************************************************************/
19: int getstr(char *strout, int maxlen, long mode)
20: {
21: int i,l,x,z; /* i=current position, l=length, j=printed chars */
22: /* x&z=misc */
23: uchar ch,str1[256],str2[256],ins=0,atr;
24:
25: console&=~CON_UPARROW;
26: sys_status&=~SS_ABORT;
27: if(mode&K_LINE && useron.misc&ANSI && !(mode&K_NOECHO)) {
28: attr(color[clr_inputline]);
29: for(i=0;i<maxlen;i++)
30: outchar(SP);
31: bprintf("\x1b[%dD",maxlen); }
32: if(wordwrap[0]) {
33: strcpy(str1,wordwrap);
34: wordwrap[0]=0; }
35: else str1[0]=0;
36: if(mode&K_EDIT)
37: strcat(str1,strout);
38: if(strlen(str1)>maxlen)
39: str1[maxlen]=0;
40: atr=curatr;
41: if(!(mode&K_NOECHO)) {
42: if(mode&K_AUTODEL && str1[0]) {
43: i=(color[clr_inputline]&0x77)<<4;
44: i|=(color[clr_inputline]&0x77)>>4;
45: attr(i); }
46: rputs(str1);
47: if(mode&K_EDIT && !(mode&(K_LINE|K_AUTODEL)) && useron.misc&ANSI)
48: bputs("\x1b[K"); /* destroy to eol */ }
49:
50: i=l=strlen(str1);
51: if(mode&K_AUTODEL && str1[0] && !(mode&K_NOECHO)) {
52: ch=getkey(mode|K_GETSTR);
53: attr(atr);
54: if(isprint(ch) || ch==0x7f) {
55: for(i=0;i<l;i++)
56: bputs("\b \b");
57: i=l=0; }
58: else {
59: for(i=0;i<l;i++)
60: outchar(BS);
61: rputs(str1);
62: i=l; }
63: if(ch!=SP && ch!=TAB)
64: ungetkey(ch); }
65:
66: while(!(sys_status&SS_ABORT) && (ch=getkey(mode|K_GETSTR))!=CR && online) {
67: if(sys_status&SS_ABORT)
68: break;
69: if(ch==LF) /* Ctrl-J same as CR */
70: break;
71: if(!i && mode&K_UPRLWR && (ch==SP || ch==TAB))
72: continue; /* ignore beginning white space if upper/lower */
73: if(mode&K_E71DETECT && ch==(CR|0x80) && l>1) {
74: if(strstr(str1,"��")) {
75: bputs("\r\n\r\nYou must set your terminal to NO PARITY, "
76: "8 DATA BITS, and 1 STOP BIT (N-8-1).\7\r\n");
77: return(0); } }
78: switch(ch) {
79: case 1: /* Ctrl-A for ANSI */
80: if(!(mode&K_MSG) || useron.rest&FLAG('A') || i>maxlen-3)
81: break;
82: if(ins) {
83: if(l<maxlen)
84: l++;
85: for(x=l;x>i;x--)
86: str1[x]=str1[x-1];
87: rprintf("%.*s",l-i,str1+i);
88: rprintf("\x1b[%dD",l-i);
89: if(i==maxlen-1)
90: ins=0; }
91: outchar(str1[i++]=1);
92: break;
93: case 2: /* Ctrl-B Beginning of Line */
94: if(useron.misc&ANSI && i && !(mode&K_NOECHO)) {
95: bprintf("\x1b[%dD",i);
96: i=0; }
97: break;
98: case 4: /* Ctrl-D Delete word right */
99: if(i<l) {
100: x=i;
101: while(x<l && str1[x]!=SP) {
102: outchar(SP);
103: x++; }
104: while(x<l && str1[x]==SP) {
105: outchar(SP);
106: x++; }
107: bprintf("\x1b[%dD",x-i); /* move cursor back */
108: z=i;
109: while(z<l-(x-i)) { /* move chars in string */
110: outchar(str1[z]=str1[z+(x-i)]);
111: z++; }
112: while(z<l) { /* write over extra chars */
113: outchar(SP);
114: z++; }
115: bprintf("\x1b[%dD",z-i);
116: l-=x-i; } /* l=new length */
117: break;
118: case 5: /* Ctrl-E End of line */
119: if(useron.misc&ANSI && i<l) {
120: bprintf("\x1b[%dC",l-i); /* move cursor to eol */
121: i=l; }
122: break;
123: case 6: /* Ctrl-F move cursor forewards */
124: if(i<l && (useron.misc&ANSI)) {
125: bputs("\x1b[C"); /* move cursor right one */
126: i++; }
127: break;
128: case 7:
129: if(!(mode&K_MSG))
130: break;
131: if(useron.rest&FLAG('B')) {
132: if (i+6<maxlen) {
133: if(ins) {
134: for(x=l+6;x>i;x--)
135: str1[x]=str1[x-6];
136: if(l+5<maxlen)
137: l+=6;
138: if(i==maxlen-1)
139: ins=0; }
140: str1[i++]='(';
141: str1[i++]='b';
142: str1[i++]='e';
143: str1[i++]='e';
144: str1[i++]='p';
145: str1[i++]=')';
146: if(!(mode&K_NOECHO))
147: bputs("(beep)"); }
148: if(ins)
149: redrwstr(str1,i,l,0);
150: break; }
151: if(ins) {
152: if(l<maxlen)
153: l++;
154: for(x=l;x>i;x--)
155: str1[x]=str1[x-1];
156: if(i==maxlen-1)
157: ins=0; }
158: if(i<maxlen) {
159: str1[i++]=7;
160: if(!(mode&K_NOECHO))
161: outchar(7); }
162: break;
163: case 14: /* Ctrl-N Next word */
164: if(i<l && (useron.misc&ANSI)) {
165: x=i;
166: while(str1[i]!=SP && i<l)
167: i++;
168: while(str1[i]==SP && i<l)
169: i++;
170: bprintf("\x1b[%dC",i-x); }
171: break;
172: case 0x1c: /* Ctrl-\ Previous word */
173: if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) {
174: x=i;
175: while(str1[i-1]==SP && i)
176: i--;
177: while(str1[i-1]!=SP && i)
178: i--;
179: bprintf("\x1b[%dD",x-i); }
180: break;
181: case 18: /* Ctrl-R Redraw Line */
182: if(!(mode&K_NOECHO))
183: redrwstr(str1,i,l,0);
184: break;
185: case TAB:
186: if(!(i%TABSIZE)) {
187: if(ins) {
188: if(l<maxlen)
189: l++;
190: for(x=l;x>i;x--)
191: str1[x]=str1[x-1];
192: if(i==maxlen-1)
193: ins=0; }
194: str1[i++]=SP;
195: if(!(mode&K_NOECHO))
196: outchar(SP); }
197: while(i<maxlen && i%TABSIZE) {
198: if(ins) {
199: if(l<maxlen)
200: l++;
201: for(x=l;x>i;x--)
202: str1[x]=str1[x-1];
203: if(i==maxlen-1)
204: ins=0; }
205: str1[i++]=SP;
206: if(!(mode&K_NOECHO))
207: outchar(SP); }
208: if(ins && !(mode&K_NOECHO))
209: redrwstr(str1,i,l,0);
210: break;
211: case BS:
212: if(!i)
213: break;
214: i--;
215: l--;
216: if(i!=l) { /* Deleting char in middle of line */
217: outchar(BS);
218: z=i;
219: while(z<l) { /* move the characters in the line */
220: outchar(str1[z]=str1[z+1]);
221: z++; }
222: outchar(SP); /* write over the last char */
223: bprintf("\x1b[%dD",(l-i)+1); }
224: else if(!(mode&K_NOECHO))
225: bputs("\b \b");
226: break;
227: case 22: /* Ctrl-V Center line */
228: str1[l]=0;
229: l=bstrlen(str1);
230: if(!l) break;
231: for(x=0;x<(maxlen-l)/2;x++)
232: str2[x]=SP;
233: str2[x]=0;
234: strcat(str2,str1);
235: strcpy(strout,str2);
236: l=strlen(strout);
237: if(mode&K_NOECHO)
238: return(l);
239: if(mode&K_MSG)
240: redrwstr(strout,i,l,K_MSG);
241: else {
242: while(i--)
243: bputs("\b");
244: bputs(strout);
245: if(mode&K_LINE)
246: attr(LIGHTGRAY); }
247: CRLF;
248: return(l);
249: case 23: /* Ctrl-W Delete word left */
250: if(i<l) {
251: x=i; /* x=original offset */
252: while(i && str1[i-1]==SP) {
253: outchar(BS);
254: i--; }
255: while(i && str1[i-1]!=SP) {
256: outchar(BS);
257: i--; }
258: z=i; /* i=z=new offset */
259: while(z<l-(x-i)) { /* move chars in string */
260: outchar(str1[z]=str1[z+(x-i)]);
261: z++; }
262: while(z<l) { /* write over extra chars */
263: outchar(SP);
264: z++; }
265: bprintf("\x1b[%dD",z-i); /* back to new x corridnant */
266: l-=x-i; } /* l=new length */
267: else {
268: while(i && str1[i-1]==SP) {
269: i--;
270: l--;
271: if(!(mode&K_NOECHO))
272: bputs("\b \b"); }
273: while(i && str1[i-1]!=SP) {
274: i--;
275: l--;
276: if(!(mode&K_NOECHO))
277: bputs("\b \b"); } }
278: break;
279: case 24: /* Ctrl-X Delete entire line */
280: if(mode&K_NOECHO)
281: l=0;
282: else {
283: while(i<l) {
284: outchar(SP);
285: i++; }
286: while(l) {
287: l--;
288: bputs("\b \b"); } }
289: i=0;
290: break;
291: case 25: /* Ctrl-Y Delete to end of line */
292: if(useron.misc&ANSI && !(mode&K_NOECHO)) {
293: bputs("\x1b[K");
294: l=i; }
295: break;
296: case 31: /* Ctrl-Minus Toggles Insert/Overwrite */
297: if(!(useron.misc&ANSI) || mode&K_NOECHO)
298: break;
299: if(ins) {
300: ins=0;
301: redrwstr(str1,i,l,0); }
302: else if(i<l) {
303: ins=1;
304: bprintf("\x1b[s\x1b[%dC",79-lclwx()); /* save pos */
305: z=curatr; /* and got to EOL */
306: attr(z|BLINK|HIGH);
307: outchar('�');
308: attr(z);
309: bputs("\x1b[u"); } /* restore pos */
310: break;
311: case 0x1e: /* Ctrl-^ */
312: if(!(mode&K_EDIT))
313: break;
314: if(i>l)
315: l=i;
316: str1[l]=0;
317: strcpy(strout,str1);
318: if((stripattr(strout) || ins) && !(mode&K_NOECHO))
319: redrwstr(strout,i,l,K_MSG);
320: if(mode&K_LINE && !(mode&K_NOECHO))
321: attr(LIGHTGRAY);
322: console|=CON_UPARROW;
323: return(l);
324: case 0x1d: /* Ctrl-] Reverse Cursor Movement */
325: if(i && (useron.misc&ANSI) && !(mode&K_NOECHO)) {
326: bputs("\x1b[D"); /* move cursor left one */
327: i--; }
328: break;
329: case 0x7f: /* Ctrl-BkSpc (DEL) Delete current char */
330: if(i==l)
331: break;
332: l--;
333: z=i;
334: while(z<l) { /* move the characters in the line */
335: outchar(str1[z]=str1[z+1]);
336: z++; }
337: outchar(SP); /* write over the last char */
338: bprintf("\x1b[%dD",(l-i)+1);
339: break;
340: default:
341: if(mode&K_WRAP && i==maxlen && ch>=SP && !ins) {
342: str1[i]=0;
343: if(ch==SP && !(mode&K_CHAT)) { /* don't wrap a space */
344: strcpy(strout,str1); /* as last char */
345: if(stripattr(strout) && !(mode&K_NOECHO))
346: redrwstr(strout,i,l,K_MSG);
347: if(!(mode&K_NOECHO))
348: CRLF;
349: return(i); }
350: x=i-1;
351: z=1;
352: wordwrap[0]=ch;
353: while(str1[x]!=SP && x)
354: wordwrap[z++]=str1[x--];
355: if(x<(maxlen/2)) {
356: wordwrap[1]=0; /* only wrap one character */
357: strcpy(strout,str1);
358: if(stripattr(strout) && !(mode&K_NOECHO))
359: redrwstr(strout,i,l,K_MSG);
360: if(!(mode&K_NOECHO))
361: CRLF;
362: return(i); }
363: wordwrap[z]=0;
364: if(!(mode&K_NOECHO))
365: while(z--) {
366: bputs("\b \b");
367: i--; }
368: strrev(wordwrap);
369: str1[x]=0;
370: strcpy(strout,str1);
371: if(stripattr(strout) && !(mode&K_NOECHO))
372: redrwstr(strout,i,x,mode);
373: if(!(mode&K_NOECHO))
374: CRLF;
375: return(x); }
376: if(i<maxlen && ch>=SP) {
377: if(mode&K_UPRLWR)
378: if(!i || (i && (str1[i-1]==SP || str1[i-1]=='-'
379: || str1[i-1]=='.' || str1[i-1]=='_')))
380: ch=toupper(ch);
381: else
382: ch=tolower(ch);
383: if(ins) {
384: if(l<maxlen) /* l<maxlen */
385: l++;
386: for(x=l;x>i;x--)
387: str1[x]=str1[x-1];
388: rprintf("%.*s",l-i,str1+i);
389: rprintf("\x1b[%dD",l-i);
390: if(i==maxlen-1) {
391: bputs(" \b\b");
392: ins=0; } }
393: str1[i++]=ch;
394: if(!(mode&K_NOECHO))
395: outchar(ch); } }
396: if(i>l)
397: l=i;
398: if(mode&K_CHAT && !l)
399: return(0); }
400: if(!online)
401: return(0);
402: if(i>l)
403: l=i;
404: str1[l]=0;
405: if(!(sys_status&SS_ABORT)) {
406: strcpy(strout,str1);
407: if((stripattr(strout) || ins) && !(mode&K_NOECHO))
408: redrwstr(strout,i,l,K_MSG); }
409: else
410: l=0;
411: if(mode&K_LINE && !(mode&K_NOECHO)) attr(LIGHTGRAY);
412: if(!(mode&(K_NOCRLF|K_NOECHO))) {
413: outchar(CR);
414: if(!(mode&K_MSG && sys_status&SS_ABORT))
415: outchar(LF);
416: lncntr=0; }
417: return(l);
418: }
419:
420: /****************************************************************************/
421: /* Hot keyed number input routine. */
422: /* Returns a valid number between 1 and max, 0 if no number entered, or -1 */
423: /* if the user hit 'Q' or ctrl-c */
424: /****************************************************************************/
425: long getnum(ulong max)
426: {
427: uchar ch,n=0;
428: long i=0;
429:
430: while(online) {
431: ch=getkey(K_UPPER);
432: if(ch>0x7f)
433: continue;
434: if(ch=='Q') {
435: outchar('Q');
436: if(useron.misc&COLDKEYS)
437: ch=getkey(K_UPPER);
438: if(ch==BS) {
439: bputs("\b \b");
440: continue; }
441: CRLF;
442: lncntr=0;
443: return(-1); }
444: else if(sys_status&SS_ABORT) {
445: CRLF;
446: lncntr=0;
447: return(-1); }
448: else if(ch==CR) {
449: CRLF;
450: lncntr=0;
451: return(i); }
452: else if(ch==BS && n) {
453: bputs("\b \b");
454: i/=10;
455: n--; }
456: else if(isdigit(ch) && (i*10L)+(ch&0xf)<=max && (ch!='0' || n)) {
457: i*=10L;
458: n++;
459: i+=ch&0xf;
460: outchar(ch);
461: if(i*10L>max && !(useron.misc&COLDKEYS)) {
462: CRLF;
463: lncntr=0;
464: return(i); } } }
465: return(0);
466: }
467:
468: /*****************************************************************************/
469: /* Displays or erases [WAIT] message */
470: /*****************************************************************************/
471: void waitforsysop(char on)
472: {
473: static saveatr;
474: int i,j;
475:
476: if(on) {
477: saveatr=curatr;
478: bputs(text[Wait]);
479: lclatr(LIGHTGRAY);
480: return; }
481: j=bstrlen(text[Wait]);
482: attr(saveatr);
483: for(i=0;i<j;i++)
484: bputs("\b \b");
485: }
486:
487: /****************************************************************************/
488: /* Returns 1 if a is a valid ctrl-a code, 0 if it isn't. */
489: /****************************************************************************/
490: char validattr(char a)
491: {
492:
493: switch(toupper(a)) {
494: case '-': /* clear */
495: case '_': /* clear */
496: case 'B': /* blue fg */
497: case 'C': /* cyan fg */
498: case 'G': /* green fg */
499: case 'H': /* high fg */
500: case 'I': /* blink */
501: case 'K': /* black fg */
502: case 'L': /* cls */
503: case 'M': /* magenta fg */
504: case 'N': /* normal */
505: case 'P': /* pause */
506: case 'R': /* red fg */
507: case 'W': /* white fg */
508: case 'Y': /* yellow fg */
509: case '0': /* black bg */
510: case '1': /* red bg */
511: case '2': /* green bg */
512: case '3': /* brown bg */
513: case '4': /* blue bg */
514: case '5': /* magenta bg */
515: case '6': /* cyan bg */
516: case '7': /* white bg */
517: return(1); }
518: return(0);
519: }
520:
521: /****************************************************************************/
522: /* Strips invalid Ctrl-Ax sequences from str */
523: /* Returns number of ^A's in line */
524: /****************************************************************************/
525: char stripattr(char *strin)
526: {
527: uchar str[256];
528: uchar a,c,d,e;
529:
530: e=strlen(strin);
531: for(a=c=d=0;c<e;c++) {
532: if(strin[c]==1) {
533: a++;
534: if(!validattr(strin[c+1])) {
535: c++;
536: continue; } }
537: str[d++]=strin[c]; }
538: str[d]=0;
539: strcpy(strin,str);
540: return(a);
541: }
542:
543: /****************************************************************************/
544: /* Redraws str using i as current cursor position and l as length */
545: /****************************************************************************/
546: void redrwstr(char *strin, int i, int l, char mode)
547: {
548: char str[256],c;
549:
550: sprintf(str,"%-*.*s",l,l,strin);
551: c=i;
552: while(c--)
553: outchar(BS);
554: if(mode&K_MSG)
555: bputs(str);
556: else
557: rputs(str);
558: if(useron.misc&ANSI) {
559: bputs("\x1b[K");
560: if(i<l)
561: bprintf("\x1b[%dD",l-i); }
562: else {
563: while(c<79) { /* clear to end of line */
564: outchar(SP);
565: c++; }
566: while(c>l) { /* back space to end of string */
567: outchar(BS);
568: c--; } }
569: }
570:
571: /****************************************************************************/
572: /* Outputs a string highlighting characters preceeded by a tilde */
573: /****************************************************************************/
574: void mnemonics(char *str)
575: {
576: char *ctrl_a_codes;
577: long l;
578:
579: if(!strchr(str,'~')) {
580: mnestr=str;
581: bputs(str);
582: return; }
583: ctrl_a_codes=strchr(str,1);
584: if(!ctrl_a_codes) {
585: if(str[0]=='@' && str[strlen(str)-1]=='@' && !strchr(str,SP)) {
586: mnestr=str;
587: bputs(str);
588: return; }
589: attr(color[clr_mnelow]); }
590: l=0L;
591: while(str[l]) {
592: if(str[l]=='~' && str[l+1]) {
593: if(!(useron.misc&ANSI))
594: outchar('(');
595: l++;
596: if(!ctrl_a_codes)
597: attr(color[clr_mnehigh]);
598: outchar(str[l]);
599: l++;
600: if(!(useron.misc&ANSI))
601: outchar(')');
602: if(!ctrl_a_codes)
603: attr(color[clr_mnelow]); }
604: else {
605: if(str[l]==1) { /* ctrl-a */
606: ctrl_a(str[++l]); /* skip the ctrl-a */
607: l++; } /* skip the attribute code */
608: else
609: outchar(str[l++]); } }
610: if(!ctrl_a_codes)
611: attr(color[clr_mnecmd]);
612: }
613:
614: /****************************************************************************/
615: /* Prompts user for Y or N (yes or no) and CR is interpreted as a Y */
616: /* Returns 1 for Y or 0 for N */
617: /* Called from quite a few places */
618: /****************************************************************************/
619: char yesno(char *str)
620: {
621: char ch;
622:
623: strcpy(question,str);
624: SYNC;
625: if(useron.misc&WIP) {
626: strip_ctrl(question);
627: menu("YESNO"); }
628: else
629: bprintf(text[YesNoQuestion],str);
630: while(online) {
631: if(sys_status&SS_ABORT)
632: ch=text[YN][1];
633: else
634: ch=getkey(K_UPPER|K_COLD);
635: if(ch==text[YN][0] || ch==CR) {
636: if(bputs(text[Yes]))
637: CRLF;
638: lncntr=0;
639: return(1); }
640: if(ch==text[YN][1]) {
641: if(bputs(text[No]))
642: CRLF;
643: lncntr=0;
644: return(0); } }
645: return(1);
646: }
647:
648: /****************************************************************************/
649: /* Prompts user for N or Y (no or yes) and CR is interpreted as a N */
650: /* Returns 1 for N or 0 for Y */
651: /* Called from quite a few places */
652: /****************************************************************************/
653: char noyes(char *str)
654: {
655: char ch;
656:
657: strcpy(question,str);
658: SYNC;
659: if(useron.misc&WIP) {
660: strip_ctrl(question);
661: menu("NOYES"); }
662: else
663: bprintf(text[NoYesQuestion],str);
664: while(online) {
665: if(sys_status&SS_ABORT)
666: ch=text[YN][1];
667: else
668: ch=getkey(K_UPPER|K_COLD);
669: if(ch==text[YN][1] || ch==CR) {
670: if(bputs(text[No]))
671: CRLF;
672: lncntr=0;
673: return(1); }
674: if(ch==text[YN][0]) {
675: if(bputs(text[Yes]))
676: CRLF;
677: lncntr=0;
678: return(0); } }
679: return(1);
680: }
681:
682: /****************************************************************************/
683: /* Waits for remote or local user to hit a key that is contained inside str.*/
684: /* 'str' should contain uppercase characters only. When a valid key is hit, */
685: /* it is echoed (upper case) and is the return value. */
686: /* Called from quite a few functions */
687: /****************************************************************************/
688: long getkeys(char *str, ulong max)
689: {
690: uchar ch,n=0,c;
691: ulong i=0;
692:
693: strupr(str);
694: while(online) {
695: ch=getkey(K_UPPER);
696: if(max && ch>0x7f) /* extended ascii chars are digits to isdigit() */
697: continue;
698: if(sys_status&SS_ABORT) { /* return -1 if Ctrl-C hit */
699: attr(LIGHTGRAY);
700: CRLF;
701: lncntr=0;
702: return(-1); }
703: if(ch && !n && (strchr(str,ch))) { /* return character if in string */
704: outchar(ch);
705: if(useron.misc&COLDKEYS && ch>SP) {
706: while(online && !(sys_status&SS_ABORT)) {
707: c=getkey(0);
708: if(c==CR || c==BS)
709: break; }
710: if(sys_status&SS_ABORT) {
711: CRLF;
712: return(-1); }
713: if(c==BS) {
714: bputs("\b \b");
715: continue; } }
716: attr(LIGHTGRAY);
717: CRLF;
718: lncntr=0;
719: return(ch); }
720: if(ch==CR && max) { /* return 0 if no number */
721: attr(LIGHTGRAY);
722: CRLF;
723: lncntr=0;
724: if(n)
725: return(i|0x80000000L); /* return number plus high bit */
726: return(0); }
727: if(ch==BS && n) {
728: bputs("\b \b");
729: i/=10;
730: n--; }
731: else if(max && isdigit(ch) && (i*10)+(ch&0xf)<=max && (ch!='0' || n)) {
732: i*=10;
733: n++;
734: i+=ch&0xf;
735: outchar(ch);
736: if(i*10>max && !(useron.misc&COLDKEYS)) {
737: attr(LIGHTGRAY);
738: CRLF;
739: lncntr=0;
740: return(i|0x80000000L); } } }
741: return(-1);
742: }
743:
744: void center(char *str)
745: {
746: int i,j;
747:
748: j=bstrlen(str);
749: for(i=0;i<(80-j)/2;i++)
750: outchar(SP);
751: bputs(str);
752: CRLF;
753: }
754:
755:
756: int uselect(int add, int n, char *title, char *item, char *ar)
757: {
758: static uint total,num[500];
759: char str[128];
760: int i,t;
761:
762: if(add) {
763: if(ar && !chk_ar(ar,useron))
764: return(0);
765: if(!total)
766: bprintf(text[SelectItemHdr],title);
767: num[total++]=n;
768: bprintf(text[SelectItemFmt],total,item);
769: return(0); }
770:
771: if(!total)
772: return(-1);
773:
774: for(i=0;i<total;i++)
775: if(num[i]==n)
776: break;
777: if(i==total)
778: i=0;
779: sprintf(str,text[SelectItemWhich],i+1);
780: mnemonics(str);
781: i=getnum(total);
782: t=total;
783: total=0;
784: if(i<0)
785: return(-1);
786: if(!i) { /* User hit ENTER, use default */
787: for(i=0;i<t;i++)
788: if(num[i]==n)
789: return(num[i]);
790: if(n<t)
791: return(num[n]);
792: return(-1); }
793: return(num[i-1]);
794: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.