00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdio.h>
00016 #include <string.h>
00017 #include "db.h"
00018
00019 void KillText(char **mapt);
00020 void ShowText(char **mapt, dbref player);
00021
00022
00023
00024
00025 #include "db.h"
00026 #include "coolmenu.h"
00027 #include "create.h"
00028
00029 #ifndef MIN
00030 #define MIN(a,b) ((a)<(b)?(a):(b))
00031 #endif
00032 #ifndef MAX
00033 #define MAX(a,b) ((a)>(b)?(a):(b))
00034 #endif
00035
00036 int BOUNDED(int, int, int);
00037
00038 int number_of_entries(coolmenu * c)
00039 {
00040 if(c->flags & CM_ONE)
00041 return 1;
00042 if(c->flags & CM_TWO)
00043 return 2;
00044
00045 if(c->flags & CM_THREE)
00046 return 3;
00047 if(c->flags & CM_FOUR)
00048 return 4;
00049 return 1;
00050 }
00051
00052 int count_following_with(coolmenu * c, int num)
00053 {
00054 int count = 0;
00055
00056 for(; c && number_of_entries(c) >= num && count < num; c = c->next)
00057 count++;
00058 return count;
00059 }
00060
00061 void display_line(char **c, int *len, coolmenu * m)
00062 {
00063 char *ch = *c;
00064 int i;
00065
00066 sprintf(ch, "%%cb");
00067 ch += strlen(ch);
00068 for(i = 0; i < *len; i++)
00069 *(ch++) = '-';
00070 sprintf(ch, "%%c");
00071 ch += strlen(ch);
00072 *len = 0;
00073 *c = ch;
00074 }
00075
00076 static int compute_length(char *s)
00077 {
00078 int l = strlen(s);
00079 char *c;
00080
00081 for(c = s; *c; c++) {
00082 if(*c == '%')
00083 if(*(c + 1) == 'c') {
00084 if(isalpha(*(c + 2))) {
00085 c += 2;
00086 l -= 3;
00087 } else {
00088 c += 1;
00089 l -= 2;
00090 }
00091 }
00092 }
00093 return l;
00094 }
00095
00096 void display_string(char **c, int *len, coolmenu * m)
00097 {
00098 int l = strlen(m->text), lo;
00099 int p, e;
00100 int i;
00101
00102 if(m->flags & CM_NOCUT) {
00103 *len = 1;
00104 strcpy(*c, m->text);
00105 *c += strlen(*c);
00106 return;
00107 }
00108 if(m->flags & CM_CENTER) {
00109 p = MAX(*len / 2 - l / 2, 0);
00110 e = MIN(*len - 1, p + l);
00111 for(i = 0; i < p; i++)
00112 (*c)[i] = ' ';
00113 *c += p;
00114 sprintf(*c, "%%ch%%cb");
00115 *c += strlen(*c);
00116 strncpy(*c, m->text, (e - p) + 1);
00117 *c += (e - p);
00118 sprintf(*c, "%%c");
00119 *c += strlen(*c);
00120 **c = 0;
00121 *len -= e;
00122 } else {
00123 lo = l - compute_length(m->text);
00124 l = MIN(*len - 1 + lo, l);
00125 strncpy(*c, m->text, l);
00126 (*c)[l] = 0;
00127 *len -= l - lo;
00128 *c = &((*c)[l]);
00129 }
00130 }
00131
00132 void display_toggle_end(char **c, coolmenu * m)
00133 {
00134 if(m->value)
00135 sprintf(*c, " %s<%%cbX%%c%%ch>%%c",
00136 !(m->flags & CM_NO_HILITE) ? "%ch" : "");
00137 else
00138 sprintf(*c, " < >");
00139 *c += strlen(*c);
00140 }
00141
00142
00143
00144 char *stringified_value(int v)
00145 {
00146 char foo[] = "KMGTPEZY";
00147 int i = -1;
00148 static char buf[5];
00149
00150 if(v > 999) {
00151 do {
00152 i++;
00153 v /= 1000;
00154 } while (v > 999 && foo[i]);
00155
00156 if(!foo[i])
00157 i--;
00158 sprintf(buf, "%d%c", BOUNDED(0, v, 999), foo[i]);
00159 } else
00160 sprintf(buf, "%d", BOUNDED(0, v, 999));
00161 return buf;
00162 }
00163
00164 void display_number_end(char **c, coolmenu * m)
00165 {
00166 if(m->value >= 0) {
00167 sprintf(*c, " %%cg%s%4s%%c", (m->value > 0 &&
00168 !(m->
00169 flags & CM_NO_HILITE)) ? "%ch" : "",
00170 stringified_value(m->value));
00171 } else
00172 sprintf(*c, " ____");
00173 *c += strlen(*c);
00174 }
00175
00176 char *display_entry(char *ch, int maxlen, coolmenu * c)
00177 {
00178 int i, j = 0, t = 0;
00179
00180
00181
00182 if((c->flags & (LETTERFIRST)) && !(c->flags & CM_NOTOG)) {
00183 if(c->flags & CM_NUMBER)
00184 maxlen -= 5;
00185 else
00186 maxlen -= 4;
00187 t = ((c->flags & (CM_TOGGLE | CM_NUMBER)) && c->value);
00188 sprintf(ch, "%s[%c]%s ", (t &&
00189 !(c->
00190 flags & CM_NO_HILITE)) ? "%ch%cr" : "%cr",
00191 t ? (c->letter + 'A' - 'a') : c->letter, "%c");
00192 ch += strlen(ch);
00193 }
00194 if(c->flags & (RIGHTEDGES) && !(c->flags & CM_NORIGHT)) {
00195 if(c->flags & CM_NUMBER)
00196 maxlen -= 6;
00197 else
00198 maxlen -= 5;
00199 j = 1;
00200 }
00201 if(t && !(c->flags & (CM_NO_HILITE))) {
00202 sprintf(ch, "%%ch");
00203 ch += strlen(ch);
00204 }
00205 if(c->flags & CM_LINE)
00206 display_line(&ch, &maxlen, c);
00207 else
00208 display_string(&ch, &maxlen, c);
00209 if(t && !(c->flags & (CM_NO_HILITE))) {
00210 sprintf(ch, "%%c");
00211 ch += strlen(ch);
00212 }
00213 if(maxlen > 0 && !(c->flags & CM_NOCUT)) {
00214 for(i = 0; i < maxlen; i++)
00215 *(ch++) = ' ';
00216 }
00217 if(j) {
00218 if(c->flags & CM_TOGGLE)
00219 display_toggle_end(&ch, c);
00220 else if(c->flags & CM_NUMBER)
00221 display_number_end(&ch, c);
00222 *(ch++) = ' ';
00223 }
00224 *ch = 0;
00225 return ch;
00226 }
00227
00228 void display_entries(coolmenu * c, int wnum, int num, char *text)
00229 {
00230 int i;
00231 char *ch = text;
00232 int single_length = (MENU_CHAR_WIDTH / wnum);
00233
00234 for(i = 0; i < num; i++) {
00235 ch = display_entry(ch, single_length, c);
00236 c = c->next;
00237 }
00238 }
00239
00240 char **MakeCoolMenuText(coolmenu * c)
00241 {
00242 char **m;
00243 int pos = 0;
00244 int n, rn;
00245
00246 Create(m, char *, MAX_MENU_LENGTH + 1);
00247
00248
00249 while (c)
00250 if((n = number_of_entries(c)))
00251 if((rn = count_following_with(c, n))) {
00252 Create(m[pos], char, MAX_MENU_WIDTH);
00253
00254
00255 display_entries(c, n, rn, m[pos++]);
00256 while (rn > 0 && c) {
00257 rn--;
00258 c = c->next;
00259 }
00260 }
00261 return m;
00262 }
00263
00264 void CreateMenuEntry_Killer(coolmenu ** c, char *text, int flag, int id,
00265 int value, int maxvalue)
00266 {
00267 coolmenu *d, *e;
00268 char first = 'a';
00269
00270 if(!*c) {
00271 Create(*c, coolmenu, 1);
00272 d = *c;
00273 } else {
00274 for(d = *c; d->next; d = d->next);
00275 Create(d->next, coolmenu, 1);
00276 d = d->next;
00277 }
00278 if(text)
00279 d->text = strdup(text);
00280 d->flags = flag;
00281 if((flag & LETTERFIRST) && !(flag & CM_NOTOG)) {
00282
00283 for(e = *c; e; e = e->next)
00284 if(e->letter)
00285 if(e->letter >= first)
00286 first = e->letter + 1;
00287 d->letter = first;
00288 }
00289 d->id = id;
00290 d->value = value;
00291 d->maxvalue = maxvalue;
00292 }
00293
00294 void KillCoolMenu(coolmenu * c)
00295 {
00296 coolmenu *d;
00297
00298 for(; c; c = d) {
00299 d = c->next;
00300 if(c->text)
00301 free((void *) c->text);
00302 free((void *) c);
00303 }
00304 }
00305
00306 void ShowCoolMenu(dbref player, coolmenu * c)
00307 {
00308 char **ch;
00309
00310 ch = MakeCoolMenuText(c);
00311 ShowText(ch, player);
00312 KillText(ch);
00313 }
00314
00315 int CoolMenu_FPWBit(int number, int maxlen)
00316 {
00317 if(number <= maxlen)
00318 return CM_ONE;
00319 if(number <= (maxlen * 2))
00320 return CM_TWO;
00321 if(number <= (maxlen * 3))
00322 return CM_THREE;
00323 return CM_FOUR;
00324 }
00325
00326 coolmenu *SelCol_Menu(int columns, char *heading, char **strings, int type,
00327 int max)
00328 {
00329 coolmenu *c = NULL;
00330 int i, co = 0;
00331 char buf[LBUF_SIZE];
00332
00333 strcpy(buf, heading);
00334 buf[0] = toupper(buf[0]);
00335 CreateMenuEntry_Simple(&c, NULL, CM_ONE | CM_LINE);
00336 CreateMenuEntry_Simple(&c, buf, CM_ONE | CM_CENTER);
00337 CreateMenuEntry_Simple(&c, NULL, CM_ONE | CM_LINE);
00338 for(co = 0; strings[co]; co++);
00339 if(columns < 0)
00340 columns = CoolMenu_FPWBit(co, 18);
00341 for(i = 0; i < co; i++)
00342 CreateMenuEntry_Normal(&c, strings[i], columns | type, i + 1, max);
00343 CreateMenuEntry_Simple(&c, NULL, CM_ONE | CM_LINE);
00344 return c;
00345 }
00346
00347 coolmenu *SelCol_FunStringMenuK(int columns, char *heading,
00348 char *(*fun) (), int last)
00349 {
00350 coolmenu *c = NULL;
00351 int i;
00352 char buf[LBUF_SIZE];
00353 int sick = 0;
00354
00355 strcpy(buf, heading);
00356 buf[0] = toupper(buf[0]);
00357 CreateMenuEntry_Simple(&c, NULL, CM_ONE | CM_LINE);
00358 CreateMenuEntry_Simple(&c, buf, CM_ONE | CM_CENTER);
00359 if(fun(0)[0] == '%') {
00360 CreateMenuEntry_Normal(&c, fun(0), columns, 1, 0);
00361 sick = 1;
00362 }
00363 CreateMenuEntry_Simple(&c, NULL, CM_ONE | CM_LINE);
00364 if(columns < 0)
00365 columns = CoolMenu_FPWBit(last, 18);
00366 for(i = sick; i < last; i++)
00367 CreateMenuEntry_Normal(&c, fun(i), columns, i + 1 - sick, 0);
00368 CreateMenuEntry_Simple(&c, NULL, CM_ONE | CM_LINE);
00369 return c;
00370 }
00371
00372 coolmenu *SelCol_FunStringMenu(int columns, char *heading, char *(*fun) ())
00373 {
00374 int co;
00375
00376 for(co = 0; fun(co); co++);
00377 return SelCol_FunStringMenuK(columns, heading, fun, co);
00378 }