int nf_load(FILE *fp) { char *key; char line[BUFSIZ]; char back[BUFSIZ]; char tmp[BUFSIZ]; ob *tg; int phase; int lno; char *p; char *q; int sep; char *f[NT_MAXFIELD]; char *v[NT_MAXFIELD]; int fmax=NT_MAXFIELD; int fuse; int fno; char *ck; char *oldp; char *u; int pn; int i; for(i=0;i<fmax;i++) { f[i] = NULL; } sep = DEF_SEP; phase = 0; lno = 0; while(1) { tg = NULL; ck = fgets(line, BUFSIZ, fp); if(!ck) { break; } lno++; #if 0 Echo(";%d %3d %s", phase, lno, line); #endif if(!line[0]) { continue; } chomp(line); p = line; p = skipwhite(p); if(!*p) { continue; } if(*p=='#') { continue; } if(phase==0) { if(strncasecmp(p, "tab(", 4)==0) { p = p+4; q = tmp; while(*p&&*p!=')') { *q++ = *p++; } *q = '\0'; #if 0 Echo("sep '%s'\n", tmp); #endif if(tmp[0]) { sep = tmp[0]; } } if(strncasecmp(p, "format", 6)==0) { p = p+6; if(*p==sep) { phase++; p++; fno = 0; while(*p) { p = draw_word(p, tmp, BUFSIZ, sep); if(!tmp[0]) { break; } if(fno<fmax) { f[fno] = strdup(tmp); fno++; } } fuse = fno; #if 0 for(i=0;i<fuse;i++) { Echo(" %3d: %-16s\n", i, f[i]); } #endif } } continue; } if(phase>0) { strcpy(back, line); for(i=0;i<fmax;i++) { v[i] = NULL; } p = back; p = skipwhite(p); oldp = p; #if 0 Echo(" back %p\n", back); Echo(" oldp %p\n", oldp); #endif fno = 0; while(*p) { if(*p==sep) { #if 0 Echo(" fno %3d p %p *p %c\n", fno, p, *p); #endif v[fno] = oldp; *p = '\0'; fno++; p++; oldp = p; } else { p++; } } if(oldp) { v[fno] = oldp; } #if 0 for(i=0;i<fuse;i++) { Echo("v %3d '%s'\n", i, v[i]); } #endif key = NULL; for(i=0;i<fuse;i++) { if(strcasecmp(f[i],"key")==0) { key = v[i]; } } if(!key) { continue; } #if 0 Echo("key '%s'\n", key); #endif tg = nb_find_ob(key); #if 0 Echo("tg %p\n", tg); #endif if(!tg) { continue; } for(i=0;i<fuse;i++) { pn = assoc(pos_ial, f[i]); #if 0 Echo(" i %3d pn %3d 0%03d %3xH %s\n", i, pn, pn, pn, f[i]); #endif if(pn==PO_KEY) { continue; } if(tg->cob.note[pn]) { Info("overwrite note %s:%s\n", key, f[i]); } tg->cob.note[pn] = strdup(v[i]); } } } for(i=0;i<fmax;i++) { if(f[i]) free(f[i]); f[i] = NULL; } return 0; }
/* Render all the words to the screen, and run the animation one step. */ static void draw_sentence (state *s, sentence *se) { int i; Bool moved = False; if (! se) return; for (i = 0; i < se->nwords; i++) { word *w = se->words[i]; switch (s->mode) { case PAGE: if (se->anim_state != PAUSE && w->tick <= w->nticks) { int dx = w->target_x - w->start_x; int dy = w->target_y - w->start_y; double r = sin (w->tick * M_PI / (2 * w->nticks)); w->x = w->start_x + (dx * r); w->y = w->start_y + (dy * r); w->tick++; if (se->anim_state == OUT && s->mode == PAGE) w->tick++; /* go out faster */ moved = True; } break; case SCROLL: { int dx = w->target_x - w->start_x; int dy = w->target_y - w->start_y; double r = (double) w->tick / w->nticks; w->x = w->start_x + (dx * r); w->y = w->start_y + (dy * r); w->tick++; moved = (w->tick <= w->nticks); /* Launch a new sentence when: - the front of this sentence is almost off the left edge; - the end of this sentence is almost on screen. - or, randomly */ if (se->anim_state != OUT && i == 0 && se->id == s->latest_sentence) { Bool new_p = (w->x < (s->xgwa.width * 0.4) && w->x + se->width < (s->xgwa.width * 2.1)); Bool rand_p = (new_p ? 0 : !(random() % 2000)); if (new_p || rand_p) { se->anim_state = OUT; s->spawn_p = True; # ifdef DEBUG if (s->debug_p) fprintf (stderr, "%s: OUT %d (x2 = %d%s)\n", progname, se->id, se->words[0]->x + se->width, rand_p ? " randomly" : ""); # endif } } } break; default: abort(); break; } draw_word (s, se, w); } if (moved && se->anim_state == PAUSE) abort(); if (! moved) { switch (se->anim_state) { case IN: se->anim_state = PAUSE; se->pause_tick = (se->nwords * 7 * s->linger); if (se->move_chars_p) se->pause_tick /= 5; scatter_sentence (s, se); shuffle_words (s, se); # ifdef DEBUG if (s->debug_p) fprintf (stderr, "%s: PAUSE %d\n", progname, se->id); # endif break; case PAUSE: if (--se->pause_tick <= 0) { se->anim_state = OUT; s->spawn_p = True; # ifdef DEBUG if (s->debug_p) fprintf (stderr, "%s: OUT %d\n", progname, se->id); # endif } break; case OUT: # ifdef DEBUG if (s->debug_p) fprintf (stderr, "%s: DEAD %d\n", progname, se->id); # endif { int j; for (j = 0; j < s->nsentences; j++) if (s->sentences[j] == se) s->sentences[j] = 0; free_sentence (s, se); } break; default: abort(); break; } } }