Xref: utzoo comp.unix.sysv386:2739 alt.sources:2701 Path: utzoo!utgpu!cs.utexas.edu!uunet!sco!staceyc From: staceyc@sco.COM (Stacey Campbell) Newsgroups: comp.unix.sysv386,alt.sources Subject: Re: Screen packages in general (was Re: Vermont Views) Keywords: user interface Message-ID: <9090@scolex.sco.COM> Date: 5 Dec 90 19:13:38 GMT References: <274AD9FB.218D@tct.uucp> <5089@rsiatl.UUCP> <1990Nov27.165132.1335@bkj386.uucp> Sender: news@sco.COM Organization: The Santa Cruz Operation, Inc. Lines: 456 In article <1990Nov27.165132.1335@bkj386.uucp> anton@analsyn.UUCP writes: >Now CURSES may not be perfect. it may be bloated and only do >80-90% of the job, but it is there. it is also a standard, as >far as the TERMCAP/TERMINFO side goes. Agreed. Even if curses doesn't directly support some feature it will just take a little work to add the required top layer, which can then be used for other applications' development. > SVR3.2. They have colour capability in CURSES. If SCO > etc choose not to implement this for their own reasons > that's their problem. Go buy your UNIX from someone who > adhere's to the standard. Just so it is clear, SCO Unix V 3.2 (all versions) supports the stock AT&T System V 3.2 color curses. Anton is almost certainly referring to SCO Xenix. I've tossed in a fun little curses color demo at the bottom of this post, so anybody with any System V 3.2 Development System can give it a spin. > The SCO TERMINFO lacks many features that > were introduced in SVR2.0. In fact most of the SCO XENIX > implemetation of TERMINFO & utilities is riddled with > bugs. SCO Xenix comes with System V 3.[01] curses, not Sys V 2 (the clue is ACS character defines in /usr/include/tinfo.h). Historically SCO Xenix was based mostly around termcap curses simply because in the good old days BSD termcap curses was much more robust and useful than System V curses. IMHO System V 3.2 curses, and even to a degree System V 3.1 curses, are far and away better than BSD curses. > But what about customers buying the package from sortes > and other outlets? > > To put this in persspective, would you consider buying, > say, Norton Tools for DOS, if they were written so that > they used the '286 & '386 extended instructions and the > features of the VGA ? I mean this in the sense that > you HAVE to upgrade to use the program at all! System V 3.2 curses applications execute correctly on Xenix machines, terminfo files are backward compatible, though it is much nicer to use Unix terminfo files when on Xenix. There is no real system dependent issues when running a 386 Unix curses application on Xenix. The application only requires a working terminfo file. > We're also trying to produce a product which can be > installed without being an expert in TERMCAP or TERMINFO > and without having to RTFM. The terminfo(4) man page is a bit daunting. There is a reasonable Nutshell book that deals with both termcap and terminfo. Here's the demo program; #!/bin/sh # This is a shell archive (produced by shar 3.49) # To extract the files from this archive, save it to a file, remove # everything above the "!/bin/sh" line above, and type "sh file_name". # # existing files will NOT be overwritten unless -c is specified # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 212 -rw------- Makefile # 6631 -rw-rw-r-- fire.c # # ============= Makefile ============== if test -f 'Makefile' -a X"$1" != X"-c"; then echo 'x - skipping Makefile (File already exists)' else echo 'x - extracting Makefile (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Makefile' && CC= cc CFLAGS= -O -DM_TERMINFO -UM_TERMCAP LDFLAGS= -O OBJS= fire.o X #Unix LDLIBS= -lcurses -lm X #Xenix # LDLIBS= -ltinfo -lm X fire: $(OBJS) X $(CC) $(LDFLAGS) fire.o -o fire $(LDLIBS) X clean: X rm -f $(OBJS) fire SHAR_EOF chmod 0600 Makefile || echo 'restore of Makefile failed' Wc_c="`wc -c < 'Makefile'`" test 212 -eq "$Wc_c" || echo 'Makefile: original size 212, current size' "$Wc_c" fi # ============= fire.c ============== if test -f 'fire.c' -a X"$1" != X"-c"; then echo 'x - skipping fire.c (File already exists)' else echo 'x - extracting fire.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'fire.c' && #include #include #include #include X #ifndef COLOR_BLACK #define start_color() #define COLOR_PAIR(a) 0 #endif X extern double drand48(); extern void srand48(); extern long lrand48(); extern time_t time(); extern char *malloc(); extern void free(); extern unsigned int sleep(); X #define PART_COUNT 10 #define PART_VARIANCE 5 #define SIN_TABLE_SIZE 350 #define COLOR_MIXED -1 #define TABLE_SCALE(val) ((int)(val / M_PI * SIN_TABLE_SIZE)) #define BOUNDCHAR(win, y, x, char) \ X (((y) >= 0 && (y) < LINES && (x) >= 0 && (x) < COLS) ? \ X mvwaddch((win), (y), (x), (char)) : 0) #define PAT_RAND_SEQ 0x01 X typedef struct particle_t { X double y_scale; X double x_scale; X double x_inc; X double x; X int old_y, old_x; X int direction; X int color; X int sequence; X int pattern_inc; } particle_t; X typedef struct pattern_t { X char *string; X int mask; } pattern_t; X typedef struct object_t { X int rel_y, rel_x; X int part_count; X pattern_t *pattern; X int pat_cycle; X int color; X int done_count; X int life; X double y_mag, x_mag; X particle_t *particles; } object_t; X typedef struct object_list_t { X object_t *object; X struct object_list_t *next; } object_list_t; X static pattern_t Patterns[] = { X {"......+++++++******@@@@@@@", 0}, X {"|\\-/", PAT_RAND_SEQ}, X {".......ooooOOOOoooo", 0}, X {".........****.......", 0}, X {"*", 0} }; X #define PATTERN_SIZE (sizeof(Patterns) / sizeof(Patterns[0])) X static int ColorId = 1; #define RAND_COLOR() (lrand48() % ColorId + 1) X static void DoSinTable(); static void DisplayObject(); static void BuildParticles(); static object_t *BuildObject(); static void InitColors(); static void AddObject(); static void DoObjectList(); static void DeleteObject(); static void FreeMemory(); X int main(argc, argv) X int argc; char *argv[]; X { X double sin_table[SIN_TABLE_SIZE]; X object_list_t *top; X time_t show_over; X X nice(4); X printf("wait."); X fflush(stdout); X DoSinTable(sin_table); X srand48((long)time((time_t *)0)); X initscr(); X start_color(); X curs_set(FALSE); X InitColors(); X top = (object_list_t *)malloc(sizeof(object_list_t)); X top->object = BuildObject(); X top->next = 0; X show_over = time((time_t *)0) + 10000 * 60; X while (time((time_t *)0) < show_over) X { X if (! (lrand48() % 20)) X AddObject(&top); X else X if (! top) X { X sleep(1); X AddObject(&top); X } X DoObjectList(stdscr, sin_table, &top); X wrefresh(stdscr); X } X endwin(); X return 0; } X static void DoObjectList(win, sin_table, top) X WINDOW *win; double *sin_table; object_list_t **top; X { X object_list_t *now, *old; X X now = *top; X while (now) X { X DisplayObject(win, sin_table, now->object); X old = now; X now = now->next; X if (old->object->done_count >= old->object->part_count || X old->object->life < 0) X DeleteObject(old, top); X } } X static void DeleteObject(zap, top) X object_list_t *zap; object_list_t **top; X { X object_list_t *new, *last; X X if (zap == *top) X { X new = zap->next; X FreeMemory(zap); X *top = new; X return; X } X new = *top; X while (new != zap) X { X last = new; X new = new->next; X } X last->next = zap->next; X FreeMemory(zap); } X static void FreeMemory(item) X object_list_t *item; X { X free((char *)item->object->particles); X free((char *)item->object); X free((char *)item); } X static void AddObject(top) X object_list_t **top; X { X object_list_t *new_top; X X new_top = (object_list_t *)malloc(sizeof(object_list_t)); X new_top->object = BuildObject(); X new_top->next = *top; X *top = new_top; } X static object_t *BuildObject() X { X object_t *object; X X object = (object_t *)malloc(sizeof(object_t)); X object->part_count = lrand48() % PART_VARIANCE + PART_COUNT; X object->particles = (particle_t *)malloc(object->part_count * X sizeof(particle_t)); X object->pattern = &Patterns[lrand48() % PATTERN_SIZE]; X object->pat_cycle = strlen(object->pattern->string); X object->rel_y = LINES - lrand48() % 15; X object->rel_x = lrand48() % (COLS / 4 * 3) + COLS / 4 * 1 / 2; X object->color = lrand48() % 4 ? RAND_COLOR() : COLOR_MIXED; X object->done_count = 0; X object->y_mag = drand48() * 0.9 + 0.5; X object->x_mag = drand48() * 0.9 + 0.5; X object->life = lrand48() % 15 + 10; X BuildParticles(object); X X return object; } X static void DisplayObject(win, sin_table, object) X WINDOW *win; double *sin_table; object_t *object; X { X int i; X int draw_y, draw_x; X particle_t *p; X double y; X int sym; X X if (--object->life < 0) X { X for (i = 0; i < object->part_count; ++i) X { X p = &object->particles[i]; X BOUNDCHAR(win, p->old_y, p->old_x, ' '); X } X return; X } X for (i = 0; i < object->part_count; ++i) X { X p = &object->particles[i]; X if (p->x < M_PI) X { X BOUNDCHAR(win, p->old_y, p->old_x, ' '); X y = sin_table[TABLE_SCALE(p->x)] * p->y_scale; X draw_y = object->rel_y - y; X draw_x = object->rel_x + p->direction * p->x * X p->x_scale; X p->sequence += p->pattern_inc; X if (p->sequence < 0) X p->sequence = object->pat_cycle - 1; X else X if (p->sequence >= object->pat_cycle) X p->sequence = 0; X sym = object->pattern->string[p->sequence]; X BOUNDCHAR(win, draw_y, draw_x, X sym | COLOR_PAIR(p->color)); X p->old_y = draw_y; X p->old_x = draw_x; X p->x += p->x_inc; X if (p->x >= M_PI) X { X BOUNDCHAR(win, draw_y, draw_x, ' '); X ++object->done_count; X } X } X } } X static void DoSinTable(table) X double *table; X { X int i; X double inc; X double current; X X inc = M_PI / SIN_TABLE_SIZE; X for (i = 0, current = 0.0; i < SIN_TABLE_SIZE; ++i, current += inc) X { X table[i] = sin(current); X if (! (i % 66)) X { X putchar('.'); X fflush(stdout); X } X } } X static void BuildParticles(object) X object_t *object; X { X int i; X particle_t *p; X X for (i = 0; i < object->part_count; ++i) X { X p = &object->particles[i]; X p->y_scale = drand48() * (LINES - 1) * object->y_mag; X p->x_scale = drand48() * COLS / 6.0 * object->x_mag; X p->x_inc = drand48() * 0.05 + 0.1; X p->x = 0.0; X p->old_y = 0; X p->old_x = 0; X p->direction = lrand48() & 1 ? -1 : 1; X if (object->pattern->mask & PAT_RAND_SEQ) X { X p->sequence = lrand48() % object->pat_cycle; X p->pattern_inc = -p->direction; X } X else X { X p->sequence = 0; X p->pattern_inc = 1; X } X if (object->color == COLOR_MIXED) X p->color = RAND_COLOR(); X else X p->color = object->color; X } } X static void InitColors() X { #ifdef COLOR_BLACK X init_pair(ColorId++, COLOR_RED, COLOR_BLACK); X init_pair(ColorId++, COLOR_GREEN, COLOR_BLACK); X init_pair(ColorId++, COLOR_YELLOW, COLOR_BLACK); X init_pair(ColorId++, COLOR_BLUE, COLOR_BLACK); X init_pair(ColorId++, COLOR_MAGENTA, COLOR_BLACK); X init_pair(ColorId++, COLOR_CYAN, COLOR_BLACK); X init_pair(ColorId, COLOR_WHITE, COLOR_BLACK); #endif } X SHAR_EOF chmod 0664 fire.c || echo 'restore of fire.c failed' Wc_c="`wc -c < 'fire.c'`" test 6631 -eq "$Wc_c" || echo 'fire.c: original size 6631, current size' "$Wc_c" fi exit 0 -- Stacey Campbell staceyc@sco.com {uunet,decwrl,ucscc,att,sq,altos,lotus,phoenix,sun,microsoft,xbs}!sco!staceyc Brought to you by Super Global Mega Corp .com