X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: fd588,4270549517893918,start X-Google-Attributes: gidfd588,public X-Google-ArrivalTime: 1994-06-06 01:06:25 PST Newsgroups: alt.ascii-art.animation Path: nntp.gmd.de!newsserver.jvnc.net!howland.reston.ans.net!agate!library.ucla.edu!news.ucdavis.edu!salsa.engr.ucdavis.edu!eswan From: eswan@salsa.engr.ucdavis.edu (Led Zeppelin) Subject: Correction for asp.tar.gz-->asp.tar Message-ID: Sender: usenet@ucdavis.edu (News Guru) Organization: College of Engineering - University of California - Davis X-Newsreader: TIN [version 1.2 PL2] Date: Mon, 6 Jun 1994 01:13:42 GMT Lines: 2631 I was told I have to uuecode this on news...I guess this is what they mean... Eric ________________________Cut Here___________________________________ COVER_LETTER >From the README: > Asp is a simplistic description language for carriage-return based ascii > animations, as commonly found in ".plan" files when you finger someone. > It is simple to use, so large, smooth, neat animations can be built > quickly and easily, and with a lot of room for imagination. Asp is a simple, rule-based language for generating those wonderful scrolling ".plan" files that many people have written diddy programs to generate. Asp was desigend to do go "one bit further" that those programs usually do, and to be flexible with it. It seems to achieve this end. I hope you have fun with it. The most obvious problem you might have is the standard index()/strchr() incompatibility. Check "asp.h" alec -- INET: aem@aber.ac.uk JANET: aem@uk.ac.aber BITNET: aem%aber@ukacrl UUCP: ...!mcsun!ukc!aber!aem ARPA: aem%uk.ac.aber@nsfnet-relay.ac.uk SNAIL: Alec Muffett, Computer Unit, Llandinam UCW, Aberystwyth, UK, SY23 3DB n ----------------------------------------------------------- COVER_LETTER 1 letter to go with distribution MANIFEST 1 This file Makefile 1 Makefile (Oh, come on!!!) README 1 documentation on programming ASP anim.c 1 animation primitives asp.c 1 main() asp.h 1 header file with major declarations copy.c 1 string copying primitives demo1.asp 1 demo 1 of asp in action demo2.asp 1 demo 2 of asp in action demo3.asp 1 demo 3 of asp in action demo4.asp 1 demo 4 of asp in action demo5.asp 1 demo 5 of asp in action display.c 1 display primitives effects.c 2 special effects ARPA: aem%uk.ac.aber@nsfnet-relay.ac.uk SNAIL: Alec Muffett, Computer Unit, Llandinam UCW, Aberystwyth, UK, SY23 3DB n CFLAGS= -g OBJECTS= anim.o asp.o copy.o display.o effects.o demo: $(EXE) $(EXE) demo1.asp 2> /dev/null $(EXE) demo2.asp 2> /dev/null $(EXE) demo3.asp 2> /dev/null $(EXE) demo4.asp 2> /dev/null $(EXE) demo5.asp 2> /dev/null $(EXE): $(OBJECTS) cc $(CFLAGS) -o $@ $(OBJECTS) clean: rm -f *.o asp anim.c 1 animation primitives asp.c 1 main() asp.h 1 header file with major declarations copy.c 1 string copyiREADME (c) Alec Muffett, September 1991 As detailed in the demonstration programs (just type 'make'), this is "asp", Alec's Scrolling Program, a diddy little hack I put together to finish a war over who could make the longest, best, and prettiest ".plan" files, using only the printable ascii character set. Asp is a simplistic description language for carriage-return based ascii animations, as commonly found in ".plan" files when you finger someone. It is simple to use, so large, smooth, neat animations can be built quickly and easily, and with a lot of room for imagination. The language is crude, I haven't put together a decent lexical analyser, there is no real parser as such, to whit, it is a realio trulio hack, as stated before. The language divides roughly into three sections: boring effects, special effects, and directives. A good idea of how they work can be obtained from the demo files supplied with this distribution, but here's a little primer anyway:- *** Primer Asp works by reading a "asp program" which is full of "rules" and "data". A "rule" line is made up of a series of "commands", all of which begin with a "." character. With me so far ? So, for example, a "rule" line might look like:- .clear .p .p .show .p .p Since the commands all begin with a dot, the rule line begins with a dot also. Any line which begins with a dot in an asp program is assumed to be a "rule" line. If a rule line is too long for convenience's sake, it may be broken with a backslash at the end of the line, in the same way as in C and shell scripts, eg: .speed 2 \ .object his -30 40 \ .object dreams, -50 44 \ .object computer -15 22 \ .object he -2 58 \ .object ? -250 61 \ .object can 89 31 \ .object have 100 35 \ .object can 111 52 \ .object A 150 20 \ .object 't 200 55 \ .anim .resetanim .p .p .p .nl - is a single rule line. When a valid rule line is encountered, it is stored in memory and becomes the "current rule". Next, Data lines. Any non-blank line which is not a rule line, is a "data line". When a data line is encountered, asp applies all the commands specified in the current rule to the data line, and then moves onto the next data line. eg: .show .nl Hello World! Will print the line "Hello World!" (.show), and throw a linefeed (.nl). Blank lines in an asp program are ignored, and so, on occasions, dummy data lines must be supplied to asp in order to get a rule to do anything. The traditional dummy line consists of two hyphens on a line of their own, eg: .p .p .p -- Invokes the Pause function (.p) three times. If there were no dummy line before the next rule was specified, the command would be ignored. Note that the Pause function does not print anything on the standard output, so the appearance of the line is not changed. Similarly, the command: .p .p .p -- -- -- Invokes Pause nine times, three times for each dummy line. Next, asp internals. Asp pinches an idea from the curses library, in that it stores a copy of what the current output line looks like, and then prints only the differences between the current line and what you want it to look like. This "optimised refresh" improves on how an asp program looks when you view it, and also on the size of the output file asp generates compared to other scrolling programs. You should also note that asp does not begin processing of a program until it encounters the first "rule line". Up to that point it behaves in the same way as the 'cat' program, copying the program to stdout. This allows you to embed a lot of plain text in your program before you start scrolling things about. *** Undercoat The above gives a fairly simple introduction to how asp works. Now for a description of commands in detail. The asp commands break down into three rough types: Boring effects, Special effects, and Directives. Some of these take arguments, which are either VALUES, BOOLEANS, or STRINGS. Values are basically any integer quantity, positive or negative. Booleans are the same as values, where 0=FALSE and Non-0=TRUE. Strings are continuous sets of characters which do not contain whitespace (I haven't bothered in putting an escaping mechanism for spaces yet.) There may be a problem if you specify a string as an argument to a command, and the string happens to begin with a dot - asp will, at some point, try to treat it as a command. Don't worry about this, it will probably work out okay, and I'll fix it in due course. Finally, please note that asp uses only columns 0->78 of the screen, because some terminals will wrap immediately you write a character into column 79, and this spoils the fun... IMPORTANT: Asp does not expand TABs in asp programs. Run your program through "expand" before feeding it into "asp". *** Topcoat Here is a list of asp directives and effects, their function and arguments: ------------------------------- DIRECTIVES AND BORING EFFECTS:- ------------------------------- .clear Wipes the current line clear and refreshes it, so as to put a blank line on screen. ------------------------------- .wipe Wipes the current line clear without refreshing it, so that the next command does not have to worry about the mess left by previous lines. This command is probably best tagged onto the beginning of every rule where you do not want to have to specifically overstrike anything that was left by the previous rule & data. ------------------------------- .nl Throws a newline. Please note that the default action of asp once it has acquired a rule it to print EVERYTHING without newlines, so you must be explicit about where you want them. ------------------------------- .show Does a .wipe and then prints the current line on screen. This is the most basic of the output primitives, and you will probably use this a lot. ------------------------------- .p Generates a pause in the display by firing approximately 2Kb of carriage returns at your screen (roughly 1 second at 9600 baud). See also ".speed" below. ------------------------------- .noop Does bugger all. ------------------------------- .flush Is a nice one. It deletes the current rule from asp's memory, so it's behaviour is once again like 'cat' (check the 'Undercoat' section, above). This means you can embed small bits of asp code in any text file, without having to modify the rest of the file to get it through the asp processor. Do NOT forget to invoke ".flush" with a dummy data line, though: This is a bit of cat'ted text. .speed 3 .spatter .p .p .p .nl This is a somewhat longer bit of asp'ed text .flush -- This is another bit of cat'ted text. - ok ? ------------------------------- .smooth BOOLEAN Switches on 80-character smoothing mode. This is useful where you are going to be scrolling small bits of text back and forth across the screen. If you do not have smoothing on, asp will generate code which will make the object move faster towards the left hand side of the screen. This is due to the optimised refresh code mentioned above. If smoothing is swithched on (".smooth 1"), asp pads out (with carriage returns) each line that it prints in order to remedy this situation. This leads to smoother, neater animations. ------------------------------- .speed VALUE This is a speed adjustment function which pads out each line that asp sends, in order to cope with fast terminals, and for special effects. The default is ".speed 0" and as the speed value is increased, each line is padded with 'x' carriage returns (x = 8 * n, where 'n' is the argument to ".speed"). The higher the value, the slower it goes. Be judicious with your use of .speed - remember, some people still work at under 1200 baud. ------------------------------- .background .foreground These are both commands which break the rules outlined above. They both read the next line DIRECTLY BENEATH the command into special buffers for use during output. It does not matter whether this line is blank or not, and indeed, a blank line will be necessary to reset the buffer to a blank when desired. ".background" and ".foreground" load their following line into a background or foreground buffer respectively. The buffer will then be used either be used as a backdrop or overlay mask for whatever is printed from then on. This means that you don't have to worry about your landscapes getting corrupted, having to redraw them, and so on. As an example, see the two occurances of ".background" in "demo2.asp" ------------------------------- SPECIAL EFFECTS:- ------------------------------- .fade Prints the message on the screen and fades it one character at a time. To get slower fades, whack the speed up either side of it, eg: .show .p .p .speed 10 .fade .speed 0 .p This piece of text should fade quite gradually into nothingness... ------------------------------- .flash Flashes all the text in a data line several times before moving onto the next. Does not overstrike text with whitespace, and can be used thusly: .show "Beep Beep", went the little car's horn. .speed 20 .flash .speed 0 Beep Beep ------------------------------- .layb .layetm .laymte .layf Prints the line by laying down one character at a time, backwards, ends-to-middle, middle-to-ends, or forwards, respectively. See the demos for examples. ------------------------------- .tshow Is like ".show" but does not call ".wipe", and it uses transparent whitespace, ie: whitespace in the data line does not overstrike any printable character that is already on screen. eg: .tshow .p LIFE ON UNIX ------------------------------- .letter1 .letter2 .letter3 Are effects macros based on the "let's-cycle-through-the-ascii-character-set" principle. See the demos for examples. ------------------------------- .scrollb .scrollf Scrolls the data line backwards or forwards (respectively) onto the screen, overstriking what is already there, eg: .scrollb .p .p This message will scroll from right to left across the width of the screen This message will also scroll from right to left. ------------------------------- .scrollob .scrollof Like .scroll[bf], but these commands scroll what it already there off of the screen, rather than overstriking it. See the demos for examples. .scrollob .p .p This message will scroll from right to left across the width of the screen This message will also scroll from right to left, without overstriking. ------------------------------- .spatter .wspatter ".spatter" is the opposite of ".fade". ".wspatter" is similar, but spatters whole words onto the screen, rather than characters. ------------------------------- .object STRING1 VALUE1 VALUE2 .anim .resetanim These are the three Asp animation primitives. Basically, the idea of an animation is to build up a series of "objects" using the ".object" directive. This specifies that you want to move "STRING1" from position VALUE1 to position VALUE2, where the value is between +/-37267 (or possibly larger), and position 0 is the left hand column of the screen, position 78 the right hand corner of the screen. After specifying the series of objects to be animated, the animation is run by invoking the ".anim" command. Once you are finished with the animation, you delete the objects from the screen by the ".resetanim" command. Simple, eh ? Here's the lorry animation from demo1.asp: .object oo-oP -15 80 .anim .resetanim .p -- Clever people will see that if you want to produce delays and odd timing effects, you merely have to start an object a long way away from it's destination. eg: several lorries- .object oo-oP -15 80 \ .object oo-oP -21 80 \ .object oo-oP -27 80 \ .object oo-oP -33 80 \ .object oo-oP -39 80 \ .object ooo-----ooP -45 80 \ .anim .resetanim .p -- Because their nature is that of a sort of "compound command", several animations can be built into a single rule and then fired off upon multiple data lines. Add a few extra dummy lines to the animation above to get a whole convoy. (see also the "flying arrows" in demos 3 & 5). For the technically minded, asp animations run in an entirely separate buffer from the rest of asp. The buffer lies in the second position thus:- USER VIEW | V FOREGROUND BUFFER ANIMATIONS BUFFER RULE BUFFER (STDLINE) BACKGROUND BUFFER Hence, what you do in an animation cannot affect the rule buffer (ie: where your data lines end up after being processed by a rule), nor the foregrounds and backgrounds. *** Usage Now for the easy bit: for your file "aspprog.asp"; asp aspprog.asp > $HOME/.plan or, if you must use tabs expand < aspprog.asp | asp > $HOME/.plan Bugs, reports, suggestions, patches to the address below... alec 8-) -- INET: aem@aber.ac.uk JANET: aem@uk.ac.aber BITNET: aem%aber@ukacrl UUCP: ...!mcsun!ukc!aber!aem ARPA: aem%uk.ac.aber@nsfnet-relay.ac.uk SNAIL: Alec Muffett, Computer Unit, Llandinam UCW, Aberystwyth, UK, SY23 3DB --------- DIRECTIVES AND BORING EFFECTS:- ------------------------------- .clear Wipes the current line clear and refreshes it, so as to put a blank line on screen. -------------------------anim.c * This code is copyright ADE Muffett, September 1991, and is distributed as * part of the ASP .plan description language compiler. This code is freely * redistributable as long as this copyright notice remains intact. No * responsibility is assumed by the author for any situation which arises * from the use of this code, including insanity, late nights, or disk * storage problems. */ #include "asp.h" void AddObject (string) char *string; { register int i; int start; int finish; char buff[SCREENWIDTH]; char *obj; sscanf (string, "%*s %s %d %d", buff, &start, &finish); obj = CopyString (buff); for (i = 0; aobjects[i].object && (i < MAX_ANIM_OBJS - 1); i++); aobjects[i].object = obj; aobjects[i].location = start; aobjects[i].destination = finish; aobjects[++i].object = NULL; } void ResetAnim () { aobjects[0].object = NULL; NullSet (anim_buffer, sizeof (anim_buffer)); } void Animate () { register int i; struct anim_object *ap; int changed; for (changed = 1; changed; /* nothing */ ) { changed = 0; NullSet (anim_buffer, sizeof (anim_buffer)); SpaceFlood (anim_buffer, SCREENWIDTH); for (i = 0; aobjects[i].object && (i < MAX_ANIM_OBJS - 1); i++) { ap = &aobjects[i]; LimCopy (anim_buffer, ap -> object, ap -> location); if (ap -> location > ap -> destination) { ap -> location--; changed++; } else if (ap -> location < ap -> destination) { ap -> location++; changed++; } } /* anim_buffer is dealt with in Update() for masking reasons */ UpdateCR (); } } ommand does not have to worry about the mess left by previous lines. This command is probably best tagged onto the beginning of every rule where you do not want to have to specifically overstrike anything that was left by the previous rule & data. ------------------------------- .nl Throws a newline. Please note that the default action of asp once it has acquired a rule it to print EVERYTHING without newlines, so you muasp.c * This code is copyright ADE Muffett, September 1991, and is distributed as * part of the ASP .plan description language compiler. This code is freely * redistributable as long as this copyright notice remains intact. No * responsibility is assumed by the author for any situation which arises * from the use of this code, including insanity, late nights, or disk * storage problems. */ /* Unix is a Bellmark of Lab Tradeoratories */ #include "asp.h" #undef TESTING /* GLOBAL DATA */ int speed; int smooth; char stdline[SCREENWIDTH + 1]; char anim_buffer[SCREENWIDTH + 1]; char foreground[SCREENWIDTH + 1]; char background[SCREENWIDTH + 1]; struct anim_object aobjects[MAX_ANIM_OBJS]; /* END OF GLOBAL DATA */ struct command_structure { char *codeword; void (*fn) (); char has_args; }; struct command_call { int c_index; char *invocation; }; static FILE *fp; static char version[] = "asp3.2(c)aem@aber"; static struct command_call command_calls[COMMAND_COUNT]; static struct command_structure command_name[COMMAND_COUNT]; void Smooth (command) char *command; { sscanf (command, "%*s %d", &smooth); } void Speed (command) char *command; { sscanf (command, "%*s %d", &speed); } void Flush () { command_calls[0].c_index = 0; } char * BuildArgs (commstring, name_index) char *commstring; int name_index; { char cbuf[255]; if (!strcmp (command_name[name_index].codeword, ".object") || !strcmp (command_name[name_index].codeword, ".speed") || !strcmp (command_name[name_index].codeword, ".smooth")) { return (CopyString (commstring)); } if (!strcmp (command_name[name_index].codeword, ".foreground")) { fgets (cbuf, 255, fp); NullSet (foreground, sizeof (foreground)); strncpy (foreground, cbuf, SCREENWIDTH); return ((char *) NULL); } if (!strcmp (command_name[name_index].codeword, ".background")) { fgets (cbuf, 255, fp); NullSet (background, sizeof (background)); strncpy (background, cbuf, SCREENWIDTH); return ((char *) NULL); } fprintf (stderr, "%s: NYI\n", commstring); return ((char *) 0); } void NewFunction (cw, fn, args) char *cw; void (*fn) (); char args; { static int command_count = 1; /* load commands from 1st element */ command_name[command_count].codeword = cw; command_name[command_count].fn = fn; command_name[command_count].has_args = args; command_count++; command_name[command_count].codeword = NULL; } void ParseCommands (cstring) register char *cstring; { int i; int comm_number; char *ptr; int get_next_line; char otherbuffer[255]; static char dot = '.'; comm_number = 0; command_calls[comm_number].c_index = 0; start_parsing: i = strlen (cstring) - 1; if (cstring[i] == '\\') { get_next_line = 1; cstring[i] = '\0'; } else { get_next_line = 0; } for (ptr = (char *) strchr (cstring, dot); ptr; ptr = (char *) strchr (ptr, dot)) { if (!*ptr) /* no more commands */ { break; } for (i = 1; command_name[i].codeword; i++) { if (!strncmp (ptr, command_name[i].codeword, strlen (command_name[i].codeword))) { command_calls[comm_number].c_index = i; if (command_name[i].has_args != 'Y') { command_calls[comm_number].invocation = (char *) 0; comm_number++; break; } else { command_calls[comm_number].invocation = BuildArgs (ptr, i); comm_number++; break; } } } if (!command_name[i].codeword) { fprintf (stderr, "Error: unknown command '%s'\n", ptr); } ptr++; /* make this neater */ } if (get_next_line) { fgets (otherbuffer, 255, fp); Trim (otherbuffer); cstring = otherbuffer; goto start_parsing; } command_calls[comm_number++].c_index = 0; } void ExecuteCommandsOn (dstring) register char *dstring; { register int i; register int j; for (i = 0; command_calls[i].c_index; i++) { j = command_calls[i].c_index; #ifdef TESTING printf ("executing '%s' as '%s' on \n'%s'\n", command_name[j].codeword, command_calls[i].invocation, dstring); #else (*command_name[j].fn) (command_calls[i].invocation, dstring); #endif } } int main (argc, argv) int argc; char *argv[]; { char command_buffer[255]; char line_buffer[255]; register char *ptr; register int i; static char dot = '.'; srand (time (0)); NewFunction (".wspatter", WordSpatter, 'N'); NewFunction (".wipe", Wipe, 'N'); NewFunction (".tshow", TShow, 'N'); NewFunction (".speed", Speed, 'Y'); NewFunction (".spatter", Spatter, 'N'); NewFunction (".smooth", Smooth, 'Y'); NewFunction (".show", Show, 'N'); NewFunction (".scrollof", ScrollOffForward, 'N'); NewFunction (".scrollob", ScrollOffBackward, 'N'); NewFunction (".scrollf", ScrollForward, 'N'); NewFunction (".scrollb", ScrollBackward, 'N'); NewFunction (".reset", ResetAnim, 'N'); NewFunction (".p", Pause, 'N'); NewFunction (".object", AddObject, 'Y'); NewFunction (".noop", Noop, 'N'); NewFunction (".nl", LineFeed, 'N'); NewFunction (".macro", NULL, 'N'); NewFunction (".letter3", Letter3, 'N'); NewFunction (".letter2", Letter2, 'N'); NewFunction (".letter1", Letter1, 'N'); NewFunction (".laymte", LayMiddleToEnds, 'N'); NewFunction (".layf", LayForward, 'N'); NewFunction (".layetm", LayEndsToMiddle, 'N'); NewFunction (".layb", LayBackward, 'N'); NewFunction (".foreground", Noop, 'Y'); NewFunction (".flush", Flush, 'N'); NewFunction (".flash", Flash, 'N'); NewFunction (".fade", Fade, 'N'); NewFunction (".clear", Clear, 'N'); NewFunction (".background", Noop, 'Y'); NewFunction (".anim", Animate, 'N'); if (isatty (fileno (stdin))) { if (argc == 1) { fprintf (stderr, "Usage:\t%s \n", argv[0]); exit (1); } fp = fopen (argv[1], "r"); if (!fp) { perror (argv[1]); exit (1); } } else { fp = stdin; } for (*line_buffer = '\0'; !feof (fp); *line_buffer = '\0') { fgets (line_buffer, 255, fp); if (!*line_buffer || *line_buffer == '\n') /* allow blank lines */ { if (!command_calls[0].c_index) { putchar ('\n'); } continue; } Trim (line_buffer); /* trim w/s */ if (*line_buffer == dot) { ParseCommands (line_buffer); continue; } if (!command_calls[0].c_index) /* don't faff around... */ { printf ("%s\n", line_buffer); continue; } ExecuteCommandsOn (line_buffer); } fclose (fp); printf ("\n\r%s\r", version); i = strlen (version); while (i--) { putchar (' '); } putchar ('\r'); return (0); } strlen (command_name[i].codeword))) { command_calls[comm_number].c_index = i; if (command_name[i].has_args != 'Y') { command_calls[comm_number].invocation = (char *) 0; comm_number++; break; } else { command_calls[comm_number].invocation = BuildArgs (ptr, i); comm_number++; break; } } } if (!command_name[i].codeword) { fprintf (stderr, "Error: unknown commanasp.h * This code is copyright ADE Muffett, September 1991, and is distributed as * part of the ASP .plan description language compiler. This code is freely * redistributable as long as this copyright notice remains intact. No * responsibility is assumed by the author for any situation which arises * from the use of this code, including insanity, late nights, or disk * storage problems. */ #include #define USE_INDEX /* use index instead of strchr() */ #define SCREENWIDTH 79 /* colourbook screws you up */ #define COMMAND_COUNT 1024 /* max number of commands in a rule */ #define LOOP_COUNT 2048 /* several things, eg: delay loop */ #define MAX_ANIM_OBJS 512 /* maximum number of objects in an anim */ #define DUMMY_RETURNS 8 /* speed 0 = 0; 1 = 64, 2 = 128... */ #define NUM_FLASH 16 /* number of flashes for 1 ".flash" */ /* strdup() if you have it... */ #define CopyString(xxx) ((char *)strcpy((char *)malloc(strlen(xxx)+1), xxx)) #ifdef USE_INDEX #define strchr(a,b) index(a,b) #endif struct anim_object { char *object; int location; int destination; }; extern char *BuildArgs (); extern char *Memcpy (); extern char anim_buffer[SCREENWIDTH + 1]; extern char background[SCREENWIDTH + 1]; extern char foreground[SCREENWIDTH + 1]; extern char stdline[SCREENWIDTH + 1]; extern int Update (); extern int smooth; extern int speed; extern struct anim_object aobjects[MAX_ANIM_OBJS]; extern void AddObject (); extern void Animate (); extern void CReturn (); extern void Clear (); extern void ExecuteCommandsOn (); extern void Fade (); extern void Flash (); extern void Flush (); extern void LayBackward (); extern void LayEndsToMiddle (); extern void LayForward (); extern void LayMiddleToEnds (); extern void Letter1 (); extern void Letter2 (); extern void Letter3 (); extern void LimCopy (); extern void LineFeed (); extern void NewFunction (); extern void Noop (); extern void NullSet (); extern void Overlay (); extern void ParseCommands (); extern void Pause (); extern void ResetAnim (); extern void ScrollBackward (); extern void ScrollForward (); extern void ScrollOffBackward (); extern void ScrollOffForward (); extern void Show (); extern void Smooth (); extern void SpaceFlood (); extern void Spatter (); extern void Speed (); extern void TShow (); extern void TransparentOverlay (); extern void Trim (); extern void UpdateCR (); extern void Wipe (); extern void WordSpatter (); else { fp = stdin; } for (*line_buffer = '\0'; !feof (fp); *line_buffer = '\0') { fgets (line_buffer, 255, fp); copy.c * This code is copyright ADE Muffett, September 1991, and is distributed as * part of the ASP .plan description language compiler. This code is freely * redistributable as long as this copyright notice remains intact. No * responsibility is assumed by the author for any situation which arises * from the use of this code, including insanity, late nights, or disk * storage problems. */ #include "asp.h" /* alas, for ANSI... */ char * Memcpy (to2, from, num) char *to2; register char *from; register int num; { register char *to = to2; while (num--) { *(to++) = *(from++); } return (to2); } /* Set a buffer to be full of nulls */ void NullSet (string, num) register char *string; register int num; { while (num--) { *(string++) = '\0'; } } /* Set all nulls in a buffer to be whitespace */ void SpaceFlood (string, num) register char *string; register int num; { while (num--) { if (!*string) { *string = ' '; } string++; } } /* copy source to destination without adding trailing null */ void Overlay (destination, source) register char *destination; register char *source; { while (*source) { *(destination++) = *(source++); } } /* copy source to destination without adding trailing null, except whitespace */ void TransparentOverlay (destination, source) register char *destination; register char *source; { while (*source) { if (*source != ' ') { *destination = *source; } source++; destination++; } } /* copy into a bounded buffer */ void LimCopy (to, from, start) register char *to; register char *from; register int start; { while (*from) { if (start >= 0 && start < SCREENWIDTH) { to[start] = *from; } from++; start++; } } /* END OF COPY PRIMITIVES */ ll nulls in a buffer to be whitespace */ void SpaceFlood (string, num) register char *string; register int num; { while (num--) { if (!*string) { *string = ' '; } string++; } } /*demo1.asp -- .show .p .p Beware the M25 - heavy lorries ! .object oo-oP -15 80 .anim .resetanim .p -- register char *source; { while (*source) { *(destination++) = *(source++); } } /* copy source to destination without adding trailing null, except whitespace */ void TransparentOverlay (destination, source) register char *destination; register char *source; { while (*source) { if (*source != ' ') { *destination = *source; } source++; destinademo2.asp .nl .nl .nl .p .show .p ******************* scrolling enterprises proudly presents:- ******************* .scrollob -------------------------------------------------------------------------------- .show .p .p .fade ----------------------(A Roadrunner>>>++>> Production)-------------------------- .spatter .p .p .fade ----------------------------- DAVID ATTENBOROUGH'S ----------------------------- .tshow .p LIFE ON UNIX .clear .scrollf .p .fade .p Hello and good evening. 8) .show .p .p Tonight we are going to examine the sex life of that rare and elusive creature, The Andalusian Video Snail. .object \@_ 85 40 .anim .resetanim .p -- .object \@_ 40 40 .object ? 38 38 .anim .resetanim .p -- .object _@_ 40 40 .anim .resetanim -- .object _@/ 40 85 .anim .resetanim -- .fade The Andalusian Video Snail. .show .p .p Yes, this small and unobtrusive gastropod, which has never before been studied in it's native habitat, has confused biologists for years; feeding as it does .show .p .object _@/ -5 80 .anim .resetanim .p upon the core dumps and executable images to be found on large UNIX mainframes. .clear -- .show .p .p It derives nourishment from bad blocks and thrives on operating systems where kernel crashes are frequent. There is some evidence to suggest that they are the original computer 'bugs', but this would then be a misnomer, because they are, of course, actually snails. .object \@_ 80 34 .anim .resetanim .p -- .object _@_ 34 34 .anim .resetanim .p -- .object _!_ 34 34 .anim .resetanim .p -- .object _@_ 34 34 .anim .resetanim .p -- .object _@/ 34 80 .anim .resetanim .p -- .clear -- .show .p .p No-one has yet captured one of these creatures, for whenever a snail happens onto the screen of a VDU, it immediately vanishes once the terminal has been disconnected from the network. After searching the length and breadth of the network, we are now able to bring you pictures of the extraordinary courtship and mating rituals of these snails... .fade .p .clear and mating rituals of these snails... .show .p .p .clear .nl (photographs courtesy of the digital corporation) .show .nl ___/--~ ~~~\____ _/\/ \_ /\ _/ ||\_ / \/\_ / ~ \_ .background \___/ \__/ \_ .tshow .p .wipe (ANDALUSIA) .object _@/ -20 37 .anim .p -- .object \@_ 100 62 .anim -- .object ? 60 60 .anim .p .resetanim -- .object _@/ 37 37 \ .object \@_ 62 62 .anim .p -- .object ! 60 60 .anim .p .resetanim -- .object _@/ 37 37 \ .object \@_ 60 40 \ .anim .p .resetanim -- .show .p (let us draw a delicate veil over these proceedings) .show .p .p {}{}{}CENSORED{}{}{} .object _@/ 40 60 \ .object \@_ 40 -5 \ .object {}{}{}CENSORED{}{}{} 30 30 \ .anim .p .resetanim -- .object {}{}{}CENSORED{}{}{} 30 30 \ .object _@_ 60 60 \ .anim .p -- .object 63 63 \ .anim .p .resetanim .clear -- .laymte .p .wipe - THE END - .background .wipe .nl .nl -- .layetm .p .clear This educational program has been brought to you by:- .show .p .wipe The numbers 4 and 17 The letter 'Q' and also... .spatter .p .nl .wipe .p Alec D.E. Muffett Roadrunner>>>++>> (using asp 3.2) .scrollf .p .wipe [Next week we investigate the habits of the Lothian Software Wombat.] .nl .nl -- is padded with 'x' carriage returns (x = 8 * n, where 'n' is the argument to ".speed"). The higher the value, the slower it goes. Be judicious with your use of .spdemo3.asp -- .wspatter .p .p .p .fade (C) ADE Muffett, UCW Aberystwyth, 1991. "aem@aber.ac.uk" "...!ukc!aber!aem" .spatter .p .p .fade .p A Roadrunner>>>++>> production .show .p .p .clear Hello there. I bet you're wondering what I've been up to of late. On the other hand maybe you haven't. Perhaps you don't know about scrolling ".plan" files at all ? .p .p -- .show .p .p .wipe You see (for those newcomers amongst you), a long time ago, two undergraduates here in Aberystwyth decided to have a 'war'. .p .p -- .show .p .p .clear They were (are) Alun Jones "alj8" and Kev Brooks "kkb9". .p .p -- .show .p .p .clear The war was over who could produce the 'prettiest' ".plan" file. .p .p -- .show .p .p .wipe They fought tooth and nail, with many people watching on the sidelines. Letters scrolled on and off the screen, flashed at you, it was quite amusing. .p .p -- .scrollob .p .p But then one day, I saw one effort (Kev's) that was really appalling: A huge data file that flashed, flickered and grunged its way across the screen, and I thought to myself :- "I can do much better than that!" .p .p -- .show .p .p .clear I think that in retrospect I was right. 8) I sat down, and I wrote "ASP" :- .show .nl .p .p .wipe Alec's Scrolling Program: a description language for plan files - written in fairly portable C - with a nice simple syntax - and above all, pleasant and easy to use. .nl .p .p -- .scrollb .p .p .clear So - What can you do with ASP ? (I hear you scream) .show .p .p (apart from flashing messages like this on and off of the screen) .speed 20 .flash flashing .speed 0 .clear .p .p -- .scrollf .p .p You can scroll a piece of text onto the screen line, either forwards... .scrollb .p .p ...or backwards onto the screen (just like this !) .scrollof .p .p Or what you have on the screen already can be scrolled off to the right -----> .scrollob .p .p .wipe <----------------- and ditto off to the left, as you might expect. .spatter .p .p .wipe You can spatter bits of text onto the screen .show .p .p .fade .p and then just let them fade into nothingness.... .layf .p .p .wipe Messages can be laid down letter by letter, from left to right; .layb .p .p .wipe ...and of course, ditto for messages right to left. .laymte .p .p .wipe Then there is laying messages down from the middle to the ends of the screen .layetm .p .p .wipe - and vice versa for messages, ends to middle. .laymte really build up some these... .layetm You can really build up some quite complex .laymte .p .p .fade .wipe You can really build up some quite complex special effects with only these... .letter1 but thats nothing compared to what you can do with the special text functions. BUT THATS NOTHING COMPARED TO WHAT YOU CAN DO WITH THE SPECIAL TEXT FUNCTIONS. But thats nothing compared to what you can do with the special text functions. .wipe .p .p -- .letter2 ESPECIALLY when YOU employ THE RANDOM-character-SEARCH macros. .letter1 especially WHEN you EMPLOY the random-CHARACTER-search MACROS. esPECIALLY when yoU emPLOY the random-chARACTER-sEARCH macros. ESPEcially wHEN YOu EMPloy THE RANDOM-character-SEarch macROS. especiALLY whEN you EMPLoy the ranDOM-CHARacter-seaRCH macROS. Especially when you employ the random-character-search macros. .clear .p .p -- .show .p .p .clear But the thing that really "made it" in my mind, was animation. Foregrounds and backgrounds. The whole kaboodle. .p .p .show .p .p And thus was born the Andalusian Video Snail: .object \@_ 100 50 .anim .resetanim .p .p -- .object _@_ 50 50 .anim .resetanim .p -- .object _@/ 50 100 .anim .resetanim .p .p -- .tshow .p .p .clear And everyone copied it... Foo ! .show .p .p .wipe 8) Oh well. Back to the hack. See you again soon. ps: a copy of the asp source code for this plan can be found in the file .show \ .object ----> 0 74 \ .object <---- 74 0 \ .anim .resetanim \ .object ----> 0 74 \ .object <---- 74 0 \ .anim .resetanim \ .show "demo3.asp" in the standard asp distribution. .nl .show .p Bye Now... Alec D.E. Muffett (c) 1991 lec D.E. Muffett Roadrunner>>>++>> (using asp 3.2) .scrollf .p .wipe [Next week we investigate the habits of the Lothian Software Wombat.] .nl .nl -- is padded with 'x' carriage returns (x = 8 * n, where 'n' is the argument to ".speed"). The higher the value, the slower it goes. Be judicious with your use of .spdemo4.asp Hello. .scrollob .p .p I'm sad. 8( .scrollof .p .p Do you know why I'm sad ? .scrollob .p .p No, you wouldn't. Why would you care ? .scrollof .p .p Do you want to know why I'm sad ? .scrollob .p .p No, you still wouldn't. Why would you care ? .scrollof .object \@_ 85 0 .anim .resetanim Is it because my Andalusian Video snail escaped ? .scrollob .p .p Look ! There it goes now !!! .scrollof .p .p No... .scrollob .p .p .fade .p It's not that. .spatter .p .p .fade Is it because I've been listening to too many Joy Division tracks ? I don't think so... I haven't been listening to ANY Joy Division Tracks... .object _@/ -5 80 .anim .resetanim -- .wspatter .p .p .wipe .p There it goes again. Bloody snail. I'm not really sure *WHY* I'm sad. after all... .wspatter .p .p .fade .p there aren't many screen drivers that can fade messages into nothingness... .spatter .p .p .clear .p or others which magic them up from nothingness, only to wipe them into oblivion .scrollf .p .p Scroll them in from the left .scrollob .p .p .thgir eht morf ni meht llorcS .wipe -- .speed 4 .wspatter .wipe .wspatter .wipe .wspatter .wipe .wspatter .wipe Flashing messages seem to be very much in vogue at the moment. Flashing messages seem to be very much in vogue at the moment. Flashing messages seem to be very much in vogue at the moment. Flashing messages seem to be very much in vogue at the moment. .speed 15 .show I don't like this style of flashing very much to tell the truth... .flash .wipe this flashing .speed 15 .p .wspatter .p Words can just be laid down in any old order you like, no problems at all... .speed 0 .wipe -- .layetm whether it is worth it all, being a microprocessor. Sometimes I really wonder .wipe .p -- .laymte should have been a like my mother wanted. Or whether I Scientific Calculator, .wipe .p -- .speed 0 .p .clear .p .show .p I ALWAYS WANTED TO BE A FRUIT MACHINE !!!! .wipe .layb .p .fade I wanted the fame ! .wipe .layf .p .fade I wanted the high life ! .wipe .layb .p .fade But most of all.... .show .p .p .fade I WANTED THE MONEY ! .speed 20 .spatter .p .wipe Oh well. .speed 2 \ .object his -30 40 \ .object dreams, -50 44 \ .object computer -15 22 \ .object he -2 58 \ .object ? -250 61 \ .object can 89 31 \ .object have 100 35 \ .object can 111 52 \ .object A 150 20 \ .object 't 200 55 \ .anim .resetanim .p .p .p .nl -- .show .p .p .nl .wipe Alec D.E. Muffett (using asp 3.2) ----> 0 74 \ .object <---- 74 0 \ .anim .resetanim \ .show "demo3.asp" in the standard asp distribution. .nl .show .p demo5.asp Now it's my turn to show off and show these upstarts whats IT is all about! .letter3 I spent an hour bolting a few extra effects onto ASP (v3.1) today... .speed 1 .flash .flash .speed 0 .p .wipe v3.1 .letter1 .p Setting up all sorts of miscellaneous effects which I'm not going to explain. .smooth 1 .scrollob .p I'll just let you watch what effect they have on the output. Okey-dokey ? (Oh yes, Alun, I did spot the optimisation. Looks much better now, doesn't it?) .clear .p -- .laymte First things first. a space invaders gun. Kev, your spider looks like .p .p .wipe -- .layetm At least my snail LOOKS like a snail. Pity I never brought the centipede out. .p .p .wipe -- .foreground [-----> <-----] .scrollof By centipede, of course, I mean this one... .p .scrollob -- .p .object nmmme -10 80 .anim .resetanim -- .foreground .p .p .wipe -- .show \ .object ----> 0 74 \ .object <---- 74 0 \ .anim .resetanim \ .object ----> 0 74 \ .object <---- 74 0 \ .anim .resetanim \ .show Forgive me, but I'm going to bring out the flying arrows too. I Like them. .wipe .layf .p .p I could always get back to basics I suppose. There are a few effects which .wipe .layb .p .p have been grossly under-used since this .plan war took off. .wipe .spatter .p .p .fade These poor little effects just sit idle, languishing as an unused ASP operator. They need the odd outing. .wipe .scrollf .p .p .wipe Erm... .speed 10 .wspatter .speed 0 .p .wipe Here's an idea! How about some hippy ethics to help pass the time ? .letter2 .p .wipe Ban the bomb. I mean, if it's not too much trouble ? Ok, man ? .letter3 .p .wipe Ban soap commercials on JANET! Ban Baldness. Ban Mathematics. Ban Hippies. Be Vegetarian. Real Veggie Hippies don't wear Leather. .p .show .clear .wipe .wspatter .p .p Hohum. Enough of the little in-jokes. Maybe I just ought to run the credits. .scrollof .p First and probably least, Alun Jones, alj8. It's all his fault. .scrollob .p And then kkb9, Kev Brooks, for doing such an awful effort I had to do one too. (He's improved a lot now, by the way. Not TOO much though) .scrollof .p Simon Y Sais, ssw9, who never really got the hang of it, even if it was in 'C' .scrollof [What IS the difference between C on UNIX and anywhere else, Simon?) .flash .flash .p IS C UNIX .scrollob .p Carl the hard-coding Hippy (ckw0), and JD (ccs7) for competition and enthusiasm (respectively) .speed 10 .wipe .wspatter .wipe .wspatter .wipe .wspatter .wipe .wspatter .show and all my friends: Gilly, Alun (Baronson), Michelle, Daniel and the Plyn Mob. .flash .flash Gilly .wipe .p .show .p .clear (Now you've had your names in lights, so push off!) .spatter .nl .p .flush At least I haven't succumbed to the temptation of sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full sysdd:/var: write failed, file system full Connection closed. .p .p .p .p .p .p -- .show .nl t, eg: .show .p .p .speed 10 .fade .speed 0 .p This piece of text should fade quite gradually into nothingness... ------------------------------- .flash Flashes all the text in a data line several times before moving onto the next. Does not overstrike text with whitespace, and can be used thusly: .show "Beep Beep", went the little car's horn. .speed 20 .flash .speed 0 Beep Beep ------------------------------- .layb .layetm .laymte .layf Prints the line by layineffects.c * This code is copyright ADE Muffett, September 1991, and is distributed as * part of the ASP .plan description language compiler. This code is freely * redistributable as long as this copyright notice remains intact. No * responsibility is assumed by the author for any situation which arises * from the use of this code, including insanity, late nights, or disk * storage problems. */ #include "asp.h" /* Cycle letters on the line backwards until they match the target letter */ void Letter1 (cstring, dstring) register char *cstring; register char *dstring; { int length; int changes; register int i; char c; length = strlen (dstring); for (c = '~'; c >= ' '; c--) { changes = 0; for (i = 0; i < length; i++) { if ((!isspace (dstring[i])) && dstring[i] == c) { stdline[i] = c; changes++; } } if (changes) { UpdateCR (); } } } /* Cycle letters on the line backwards until they match the target letter */ void Letter2 (cstring, dstring) register char *cstring; register char *dstring; { register int i; int changes; int length; char c; length = strlen (dstring); for (c = '~'; c >= ' '; c--) { changes = 0; for (i = 0; i < length; i++) { if ((!isspace (dstring[i])) && dstring[i] <= c) { stdline[i] = c; changes++; } } if (changes) { UpdateCR (); } } } /* Cycle letters on the line backwards until they match the target letter */ void Letter3 (cstring, dstring) register char *cstring; register char *dstring; { int length; int changes; register int i; char c; length = strlen (dstring); for (c = '~'; c >= ' '; c--) { changes = 0; for (i = 0; i < length; i++) { if ((!isspace (dstring[i])) && dstring[i] <= c) { stdline[i] = c; if (dstring[i] == c) { changes++; } } } if (changes) { UpdateCR (); } } } /* flash all printable characters on the line */ void Flash (cstring, dstring) register char *cstring; register char *dstring; { int length; int i; register int j; length = strlen (dstring); i = NUM_FLASH; while (i--) { for (j = 0; j < length; j++) { if (!isspace (dstring[j])) { stdline[j] = ' '; } } UpdateCR (); for (j = 0; j < length; j++) { if (!isspace (dstring[j])) { stdline[j] = dstring[j]; } } UpdateCR (); } } /* Spatter line down randomly */ void Spatter (cstring, dstring) register char *cstring; register char *dstring; { int length; register int i; register int dindex; length = strlen (dstring); for (i = 0; i < LOOP_COUNT; i++) { if (!length) { continue; } dindex = rand () % length; if (stdline[dindex] == dstring[dindex]) { continue; } stdline[dindex] = dstring[dindex]; UpdateCR (); } TransparentOverlay (stdline, dstring); UpdateCR (); } /* Like Spatter(), but on a by-word basis */ void WordSpatter (cstring, dstring) register char *cstring; register char *dstring; { int length; register int i; register int j; register int dindex; length = strlen (dstring); for (i = 0; i < LOOP_COUNT; i++) { if (!length) { continue; } for (dindex = rand () % length; dindex >= 0 && !isspace (dstring[dindex]); dindex--); dindex++; if (stdline[dindex] == dstring[dindex]) { continue; } while (dstring[dindex] && !isspace (dstring[dindex])) { stdline[dindex] = dstring[dindex]; dindex++; } UpdateCR (); if (!strcmp (dstring, stdline)) { break; } } TransparentOverlay (stdline, dstring); UpdateCR (); } /* Draw line and then remove, char by char */ void Fade (cstring, dstring) register char *cstring; register char *dstring; { int length; register int i; register int dindex; TransparentOverlay (stdline, dstring); UpdateCR (); for (i = 0; i < LOOP_COUNT; i++) { length = strlen (stdline); if (!length) { continue; } dindex = rand () % length; if (stdline[dindex] == ' ') { continue; } stdline[dindex] = ' '; UpdateCR (); Trim (stdline); } for (i = 0; stdline[i]; i++) { stdline[i] = ' '; } UpdateCR (); } /* Scroll characters l->r, one by one */ void ScrollForward (cstring, dstring) char *cstring; char *dstring; { register int i; register int j; register int oplength; oplength = strlen (dstring); for (i = oplength - 1; i >= 0; i--) { for (j = 0; dstring[j + i]; j++) { stdline[j] = dstring[j + i]; } UpdateCR (); } } /* Scroll characters r->l, one by one */ void ScrollBackward (cstring, dstring) char *cstring; char *dstring; { register int i; register int j; char srcbuffer[SCREENWIDTH + 1]; NullSet (srcbuffer, sizeof (srcbuffer)); strcpy (srcbuffer, dstring); SpaceFlood (srcbuffer, SCREENWIDTH); for (i = SCREENWIDTH - 1; i >= 0; i--) { for (j = 0; (j + i) < SCREENWIDTH; j++) { stdline[j + i] = srcbuffer[j]; } UpdateCR (); } } /* scroll entire line r->l, bringing on new stuff from the right */ void ScrollOffBackward (cstring, dstring) char *cstring; char *dstring; { register int i; register int j; char srcbuffer[SCREENWIDTH + 1]; NullSet (srcbuffer, sizeof (srcbuffer)); strcpy (srcbuffer, dstring); SpaceFlood (srcbuffer, SCREENWIDTH); for (i = 0; i < SCREENWIDTH; i++) { for (j = 1; j < SCREENWIDTH; j++) { stdline[j - 1] = stdline[j]; } stdline[SCREENWIDTH - 1] = srcbuffer[i]; UpdateCR (); } } /* scroll entire line l->r, bringing on new stuff from the left */ void ScrollOffForward (cstring, dstring) char *cstring; char *dstring; { register int i; register int j; char srcbuffer[SCREENWIDTH + 1]; NullSet (srcbuffer, sizeof (srcbuffer)); strcpy (srcbuffer, dstring); SpaceFlood (srcbuffer, SCREENWIDTH); for (i = SCREENWIDTH - 1; i >= 0; i--) { for (j = SCREENWIDTH - 2; j > 0; j--) { stdline[j] = stdline[j - 1]; } stdline[0] = srcbuffer[i]; UpdateCR (); } } /* Lay characters down l->r, one by one */ void LayForward (cstring, dstring) char *cstring; register char *dstring; { register int i; /* do not copy last null. */ for (i = 0; dstring[i]; i++) { stdline[i] = dstring[i]; UpdateCR (); } } /* Lay characters down r->l, one by one */ void LayBackward (cstring, dstring) char *cstring; register char *dstring; { register int i; i = strlen (dstring) - 1; /* index of last character */ if (i >= 0) { stdline[i] = dstring[i]; for ( /* nothing */ ; i >= 0; i--) { stdline[i] = dstring[i]; UpdateCR (); } } } /* Lay r->l and v.v. meeting in middle */ void LayEndsToMiddle (cstring, dstring) char *cstring; register char *dstring; { register int start; int middle; register int end; int dlength; dlength = strlen (dstring) - 1; end = dlength; for (start = 0; dstring[start] && isspace (dstring[start]); start++); if (!dstring[start]) { return; } middle = ((end - start) / 2) + start; for (; end >= middle; end--, start++) { if (start <= dlength) { stdline[start] = dstring[start]; } if (end <= dlength) { stdline[end] = dstring[end]; } UpdateCR (); } } /* Lay l->r and v.v., middle to end */ void LayMiddleToEnds (cstring, dstring) char *cstring; register char *dstring; { register int dlength; register int backwards; register int forwards; int start; int end; dlength = strlen (dstring) - 1; end = dlength; for (start = 0; dstring[start] && isspace (dstring[start]); start++); if (!dstring[start]) { return; } forwards = backwards = ((end - start) / 2) + start; for (; backwards >= start || forwards <= end;) { if (backwards >= start) { if (backwards <= dlength) { stdline[backwards] = dstring[backwards]; } backwards--; } if (forwards <= end) { if (forwards <= dlength) { stdline[forwards] = dstring[forwards]; } forwards++; } UpdateCR (); } } it already there off of the screen, rather than overstriking it. See the demos for examples. .scrollob .p .p This message will scroll from right to left across the width of the screen This message will also scroll from right to left, without overstriking. ------------------------------- .spatter .wspatter ".spatter" is the opposite of ".fade". ".wspatter" is similar, but spatters whole words onto the screen, rather than characters. --display.c * This code is copyright ADE Muffett, September 1991, and is distributed as * part of the ASP .plan description language compiler. This code is freely * redistributable as long as this copyright notice remains intact. No * responsibility is assumed by the author for any situation which arises * from the use of this code, including insanity, late nights, or disk * storage problems. */ #include "asp.h" #undef DEBUG static char currline[SCREENWIDTH + 1]; /* The state of the union... */ /* nothing */ void Noop () { } /* Throw a newline */ void LineFeed () { static char lf = '\n'; putchar (lf); NullSet (currline, sizeof (currline)); SpaceFlood (currline, sizeof (currline)); currline[SCREENWIDTH] = '\0'; } /* Throw a carriage return */ void CReturn () { static char cr = '\r'; putchar (cr); } /* Fast clear of the current line */ void Wipe () { NullSet (stdline, sizeof (stdline)); } /* Fast clear of the current line */ void Clear () { Wipe (); UpdateCR (); } /* show something onto screen destructively */ void Show (cstring, dstring) char *cstring; char *dstring; { Wipe (); Overlay (stdline, dstring); UpdateCR (); } /* show something onto screen non destructively */ void TShow (cstring, dstring) char *cstring; char *dstring; { TransparentOverlay (stdline, dstring); UpdateCR (); } /* Pause about 1 second @ 9600 baud */ void Pause () { register int i; for (i = 0; i < LOOP_COUNT; i++) { CReturn (); } for (i = (LOOP_COUNT * (speed / DUMMY_RETURNS)); i; i--) { CReturn (); } } /* Trim off all whitespace from a text line */ void Trim (ptr) register char *ptr; { while (*ptr) { ptr++; } while (isspace (*(--ptr))); *(++ptr) = '\0'; } /* the display primitive */ int Update () { register int i; int j; int print_anim; int print_stdline; char diffline[SCREENWIDTH + 1]; /* fix up all spaces */ SpaceFlood (background, SCREENWIDTH); background[SCREENWIDTH] = '\0'; Trim (background); SpaceFlood (stdline, SCREENWIDTH); stdline[SCREENWIDTH] = '\0'; Trim (stdline); SpaceFlood (anim_buffer, SCREENWIDTH); anim_buffer[SCREENWIDTH] = '\0'; Trim (anim_buffer); SpaceFlood (foreground, SCREENWIDTH); foreground[SCREENWIDTH] = '\0'; Trim (foreground); #ifdef DEBUG printf ("bg'%s'\n", background); printf ("st'%s'\n", stdline); printf ("ab'%s'\n", anim_buffer); printf ("fg'%s'\n", foreground); #endif /* zero the differences buffer */ NullSet (diffline, sizeof (diffline)); SpaceFlood (diffline, SCREENWIDTH); diffline[SCREENWIDTH] = '\0'; TransparentOverlay (diffline, background); TransparentOverlay (diffline, stdline); TransparentOverlay (diffline, anim_buffer); TransparentOverlay (diffline, foreground); Trim (diffline); /* and tidy up the memory copy of the current line */ Trim (currline); /* this is what the screen is */ i = strlen (diffline); j = strlen (currline); if (i < j) { for (; i < j && i < SCREENWIDTH; i++) { diffline[i] = ' '; } diffline[j] = '\0'; } diffline[SCREENWIDTH] = '\0'; /* there is a difference between screen and stdline+overstrikes */ if (strcmp (currline, diffline)) { char printline[SCREENWIDTH + 1]; /* backup diffline */ Memcpy (printline, diffline, sizeof (printline)); /* don't print common trailing characters except space */ if ((i = strlen (currline)) == strlen (diffline)) { while (i-- && (diffline[i] == currline[i])) { printline[i] = '\0'; } } /* print only what is necessary to make changes */ printf ("%s", printline); /* make diffline the current line */ Memcpy (currline, diffline, sizeof (currline)); /* fill out line */ return (strlen (printline)); } else { return (SCREENWIDTH); } } /* save typing */ void UpdateCR () { register int i; i = Update (); CReturn (); while (smooth && (i++ < SCREENWIDTH)) { CReturn (); } for (i = 0; i < (speed * DUMMY_RETURNS); i++) { CReturn (); } } /* END OF DISPLAY PRIMITIVES */ OffBackward (cstring, dstring) char *cstring; char *dstring; { register int i; register int j; char srcbuffer[SCREENWIDTH + 1]; NullSet (srcbuffer, sizeof (srcbuffer)); strcpy (srcbuffer, dstring); SpaceFlood (srcbuffer, SCREENWIDTH); for (i = 0; i < SCREENWIDTH; i++) { for (j = 1; j < SCREENWIDTH; j++) { stdline[j - 1] = stdline[j]; } stdline[SCREENWIDTH - 1] = s if (i >= 0) { stdline[i] = dstring[i]; for ( /* nothing */ ; i >= 0; i--) { stdline[i] = dstring[i]; UpdateCR (); } } } /* Lay r->l and v.v. meeting in middle */ void LayEndsToMiddle (cstring, dstring) char *cstring; register char *dstring; { register int start; int middle; register int end; int dlength; dlength = strlen (dstring) - 1; end = dlength; for (start = 0; dstring[start] && isspace (dstring[start]); start++); if (!dstring[start]) { return; } middle = ((end - start) / 2) + start; for (; end >= middle; end--, start++) { if (start <= dlength) { stdline[start] = dstring[start]; } if (end <= dlength) { stdline[end] = dstring[end]; } UpdateCR (); } } /* Lay l->r and v.v., middle to end */ void LayMiddleToEnds (cstring, dstring) char *cstring; register char *dstring; { register int dlength; register int backwards; register int forwards; int start; int end; dlength = strlen (dstring) - 1; end = dlength; for (start = 0; dstring[start] && isspace (dstring[start]); start++); if (!dstring[start]) { return; } forwards = backwards = ((end - start) / 2) + start; for (; backwards >= start || forwards <= end;) { if (backwards >= start) { if (backwards <= dlength) { stdline[backwards] = dstring[backwards]; } backwards--; } if (forwards <= end) { if (forwards <= dlength) { stdline[forwards] = dstring[forwards]; } forwards++; } UpdateCR (); } } it already there off of the screen, rather than overstriking it. See the demos for examples. .scrollob .p .p This message will scroll from right to left across the width of the screen This message will also scroll from right to left, without overstriking. ------------------------------- .spatter .wspatter ".spatter" is the opposite of ".fade". ".wspatter" is similar, but spatters whole words onto the screen, rather than characters. --display.c * This code is copyright ADE Muffett, September 1991, and is distributed as * part of the ASP .plan description language compiler. This code is freely * redistributable as long as this copyright notice remains intact. No * responsibility is assumed by the author for any situation which arises * from the use of this code, including insanity, late nights, or disk * storage problems. */ #include "asp.h" #undef DEBUG static char currline[SCREENWIDTH + 1]; /* The state of the union... */ /* nothing