예제 #1
0
파일: psx.c 프로젝트: 9a3eedi/Droidsound
/////////////////////////////////////////////////////////////////////////////
//
// hefile emucall handler
//
sint32 EMU_CALL psx_emucall(
  void   *state,
  uint8  *ram_native,
  uint32  ram_size,
  sint32  type,
  sint32  emufd,
  sint32  ofs,
  sint32  arg1,
  sint32  arg2
) {
  if(type == 0) {
    if(PSXSTATE->console_callback) {
      sint32 i;
      for(i = 0; i < arg1; i++) {
        char c = ram_native[ofs & (ram_size-1)]; ofs++;
        if(c == 'H') { PSXSTATE->console_enable = 1; }
        if(PSXSTATE->console_enable) {
          (PSXSTATE->console_callback)(PSXSTATE->console_context, c);
        }
      }
    }
    return arg1;
  }
  if(!(HAVE_VFS)) return -5;
  switch(type) {
  case 3: return vopen (VFSSTATE, ram_native, ram_size, ofs);
  case 4: return vclose(VFSSTATE, emufd);
  case 5: return vread (VFSSTATE, ram_native, ram_size, emufd, ofs, arg1);
  case 6: return -13; // EACCES permission denied
  case 7: return vlseek(VFSSTATE, emufd, arg1, arg2);
  default: return -5;
  }
}
예제 #2
0
파일: g_vsp.cpp 프로젝트: speveril/verge3
VSP::VSP(char *fname)
{
	VFILE *f = vopen(fname);
	if (!f)
		err("VSP::VSP() - couldn't find VSP file %s", fname);
	LoadVSP(f);
	vclose(f);
}
예제 #3
0
파일: a_image.cpp 프로젝트: speveril/verge3
corona::Image* load_image_from_packfile(const char* filename)
{
	VFILE* vf = vopen(filename);
	if (!vf)
	{
		err("loadimage: couldn't load image %s; couldnt find a file or a vfile", filename);
	}
	int l = filesize(vf);
	std::auto_ptr<char> buffer(new char[l]);
	vread(buffer.get(), l, vf);
	vclose(vf);
	std::auto_ptr<corona::File> memfile(corona::CreateMemoryFile(buffer.get(), l));
	return corona::OpenImage(memfile.get(), corona::FF_AUTODETECT, corona::PF_DONTCARE);
}
예제 #4
0
/*
  OPEN, LOCK, UNLOCK
*/
void ivopen()
{
    int obj_cnt, item;

    for (item = 1, obj_cnt = 0; item < MAXOBJ; item++) {
	if ((g.place[item] == g.loc) && (hinged(item))) {
	    object = item;
	    obj_cnt++;
	}
    }
    if (obj_cnt != 1)
	needobj();
    else if (verb == LOCK)
	vlock();
    else if (verb == UNLOCK)
	vunlock();
    else if (verb == SHUT)
	vclose();
    else
	vopen();
}
예제 #5
0
파일: ex_vops2.c 프로젝트: n-t-roff/ex-2.2
void
vappend(int ch, int cnt, int indent)
{
	register int i;
	register char *gcursor;
	bool escape;
	int repcnt;
	short oldhold = hold;

	/*
	 * Before a move in hardopen when the line is dirty
	 * or we are in the middle of the printed representation,
	 * we retype the line to the left of the cursor so the
	 * insert looks clean.
	 */
	if (ch != 'o' && state == HARDOPEN && (rubble || !ateopr())) {
		rubble = 1;
		wcursor = cursor;
		vmove();
	}
	vaifirst = indent == 0;

	/*
	 * Handle replace character by (eventually)
	 * limiting the number of input characters allowed
	 * in the vgetline routine.
	 */
	if (ch == 'r')
		repcnt = 2;
	else
		repcnt = 0;

	/*
	 * If an autoindent is specified, then
	 * generate a mixture of blanks to tabs to implement
	 * it and place the cursor after the indent.
	 * Text read by the vgetline routine will be placed in genbuf,
	 * so the indent is generated there.
	 */
	if (value(AUTOINDENT) && indent != 0) {
		gcursor = genindent(indent);
		*gcursor = 0;
		vgotoCL(qcolumn(cursor - 1, genbuf));
	} else {
		gcursor = genbuf;
		*gcursor = 0;
		if (ch == 'o')
			vfixcurs();
	}

	/*
	 * Prepare for undo.  Pointers delimit inserted portion of line.
	 */
	vUA1 = vUA2 = cursor;

	/*
	 * If we are not in a repeated command and a ^@ comes in
	 * then this means the previous inserted text.
	 * If there is none or it was too long to be saved,
	 * then beep() and also arrange to undo any damage done
	 * so far (e.g. if we are a change.)
	 */
	if ((vglobp && *vglobp == 0) || peekbr()) {
		if ((INS[0] & (OVERBUF|TRIM)) == OVERBUF) {
			beep();
			if (!splitw)
				ungetkey('u');
			doomed = 0;
			hold = oldhold;
			return;
		}
		/*
		 * Unread input from INS.
		 * An escape will be generated at end of string.
		 * Hold off n^^2 type update on dumb terminals.
		 */
		vglobp = INS;
		hold |= HOLDQIK;
	} else if (vglobp == 0)
		/*
		 * Not a repeated command, get
		 * a new inserted text for repeat.
		 */
		INS[0] = 0;

	/*
	 * For wrapmargin to hack away second space after a '.'
	 * when the first space caused a line break we keep
	 * track that this happened in gobblebl, which says
	 * to gobble up a blank silently.
	 */
	gobblebl = 0;

	/*
	 * Text gathering loop.
	 * New text goes into genbuf starting at gcursor.
	 * cursor preserves place in linebuf where text will eventually go.
	 */
	if (*cursor == 0 || state == CRTOPEN)
		hold |= HOLDROL;
	for (;;) {
		if (ch == 'r' && repcnt == 0)
			escape = 0;
		else {
			gcursor = vgetline(repcnt, gcursor, &escape);

			/*
			 * After an append, stick information
			 * about the ^D's and ^^D's and 0^D's in
			 * the repeated text buffer so repeated
			 * inserts of stuff indented with ^D as backtab's
			 * can work.
			 */
			if (HADUP)
				addtext("^");
			else if (HADZERO)
				addtext("0");
			while (CDCNT > 0)
				addtext("\204"), CDCNT--;
			if (gobbled)
				addtext(" ");
			addtext(ogcursor);
		}
		repcnt = 0;

		/*
		 * Smash the generated and preexisting indents together
		 * and generate one cleanly made out of tabs and spaces
		 * if we are using autoindent.
		 */
		if (!vaifirst && value(AUTOINDENT)) {
			i = fixindent(indent);
			if (!HADUP)
				indent = i;
			gcursor = strend(genbuf);
		}

		/*
		 * Limit the repetition count based on maximum
		 * possible line length; do output implied
		 * by further count (> 1) and cons up the new line
		 * in linebuf.
		 */
		cnt = vmaxrep(ch, cnt);
		CP(gcursor + 1, cursor);
		do {
			CP(cursor, genbuf);
			if (cnt > 1) {
				int oldhold = hold;

				Outchar = vinschar;
				hold |= HOLDQIK;
				ex_printf("%s", genbuf);
				hold = oldhold;
				Outchar = vputchar;
			}
			cursor += gcursor - genbuf;
		} while (--cnt > 0);
		endim();
		vUA2 = cursor;
		if (escape != '\n')
			CP(cursor, gcursor + 1);

		/*
		 * If doomed characters remain, clobber them,
		 * and reopen the line to get the display exact.
		 */
		if (state != HARDOPEN) {
			DEPTH(vcline) = 0;
			if (doomed > 0) {
				register int cind = cindent();

				physdc(cind, cind + doomed);
				doomed = 0;
			}
			i = vreopen(LINE(vcline), lineDOT(), vcline);
		}

		/*
		 * All done unless we are continuing on to another line.
		 */
		if (escape != '\n')
			break;

		/*
		 * Set up for the new line.
		 * First save the current line, then construct a new
		 * first image for the continuation line consisting
		 * of any new autoindent plus the pushed ahead text.
		 */
		killU();
		addtext(gobblebl ? " " : "\n");
		vsave();
		cnt = 1;
		if (value(AUTOINDENT)) {
#ifdef LISP
			if (value(LISP))
				indent = lindent(dot + 1);
			else
#endif
			     if (!HADUP && vaifirst)
				indent = whitecnt(linebuf);
			vaifirst = 0;
			strcLIN(vpastwh(gcursor + 1));
			gcursor = genindent(indent);
			*gcursor = 0;
			if (gcursor + strlen(linebuf) > &genbuf[LBSIZE - 2])
				gcursor = genbuf;
			CP(gcursor, linebuf);
		} else {
			CP(genbuf, gcursor + 1);
			gcursor = genbuf;
		}

		/*
		 * If we started out as a single line operation and are now
		 * turning into a multi-line change, then we had better yank
		 * out dot before it changes so that undo will work
		 * correctly later.
		 */
		if (vundkind == VCHNG) {
			vremote(1, (void (*)(int))yank, 0);
			undap1--;
		}

		/*
		 * Now do the append of the new line in the buffer,
		 * and update the display.  If slowopen
		 * we don't do very much.
		 */
		vdoappend(genbuf);
		vundkind = VMANYINS;
		vcline++;
		if (state != VISUAL)
			vshow(dot, NOLINE);
		else {
			i += LINE(vcline - 1);
			vopen(dot, i);
			if (value(SLOWOPEN))
				vscrap();
			else
				vsync1(LINE(vcline));
		}
		strcLIN(gcursor);
		*gcursor = 0;
		cursor = linebuf;
		vgotoCL(qcolumn(cursor - 1, genbuf));
	}

	/*
	 * All done with insertion, position the cursor
	 * and sync the screen.
	 */
	hold = oldhold;
	if (cursor > linebuf)
		cursor--;
	if (state != HARDOPEN)
		vsyncCL();
	else if (cursor > linebuf)
		back1();
	doomed = 0;
	wcursor = cursor;
	vmove();
}
예제 #6
0
//---
//setup garlick to use vfile
void *Garlick_vf_open(const char *fname) { return vopen(fname); }
예제 #7
0
/*
	Routine to process a transitive verb
*/
trverb()
{
	switch(verb){
	case CALM:
	case WALK:
	case QUIT:
	case SCORE:
	case FOO:
	case BRIEF:
	case SUSPEND:
	case HOURS:
	case LOG:
		actspk(verb);
		break;
	case TAKE:
		vtake();
		break;
	case DROP:
		vdrop();
		break;
	case OPEN:
	case LOCK:
		vopen();
		break;
	case SAY:
		vsay();
		break;
	case NOTHING:
		rspeak(54);
		break;
	case ON:
		von();
		break;
	case OFF:
		voff();
		break;
	case WAVE:
		vwave();
		break;
	case KILL:
		vkill();
		break;
	case POUR:
		vpour();
		break;
	case EAT:
		veat();
		break;
	case DRINK:
		vdrink();
		break;
	case RUB:
		if (object != LAMP)
			rspeak(76);
		else
			actspk(RUB);
		break;
	case THROW:
		vthrow();
		break;
	case FEED:
		vfeed();
		break;
	case FIND:
	case INVENTORY:
		vfind();
		break;
	case FILL:
		vfill();
		break;
	case READ:
		vread();
		break;
	case BLAST:
		vblast();
		break;
	case BREAK:
		vbreak();
		break;
	case WAKE:
		vwake();
		break;
	default:
		printf("This verb is not implemented yet.\n");
	}
}
예제 #8
0
/*
 * Fully cleanup the screen, leaving no @ lines except at end when
 * line after last won't completely fit.  The routine vsync is
 * more conservative and much less work on dumb terminals.
 */
void 
vredraw(register int p)
{
	register int l;
	register line *tp;
	char temp[LBSIZE];
	bool anydl = 0;
	short oldhold = hold;

#ifdef ADEBUG
	if (trace)
		tfixnl(), fprintf(trace, "vredraw(%d)\n", p), tvliny();
#endif
	if (holdupd) {
		holdupd = 3;
		return;
	}
	if (state == HARDOPEN || splitw)
		return;
	if (p < 0 /* || p > WECHO */)
		error(catgets(catd, 1, 221, "Internal error: vredraw"));

	/*
	 * Trim the ragged edges (lines which are off the screen but
	 * not yet logically discarded), save the current line, and
	 * search for first logical line affected by the redraw.
	 */
	vscrap();
	CP(temp, linebuf);
	l = 0;
	tp = dot - vcline;
	if (vcnt == 0)
		LINE(0) = WTOP;
	while (l < vcnt && LINE(l) < p)
		l++, tp++;

	/*
	 * We hold off echo area clearing during the redraw in deference
	 * to a final clear of the echo area at the end if appropriate.
	 */
	heldech = 0;
	hold |= HOLDECH;
	for (; l < vcnt && Peekkey != ATTN; l++) {
		if (l == vcline)
			strcLIN(temp);
		else
			getline(*tp);

		/*
		 * Delete junk between displayed lines.
		 */
		if (LINE(l) != LINE(l + 1) && LINE(l) != p) {
			if (anydl == 0 && DB && CD) {
				hold = oldhold;
				vclrech(0);
				anydl = 1;
				hold |= HOLDECH;
				heldech = 0;
			}
			vdellin(p, LINE(l) - p, l);
		}

		/*
		 * If line image is not know to be up to date, then
		 * redisplay it;  else just skip onward.
		 */
		LINE(l) = p;
		if (FLAGS(l) & VDIRT) {
			DEPTH(l) = vdepth();
			if (l != vcline && p + DEPTH(l) - 1 > WBOT) {
				vscrap();
				break;
			}
			FLAGS(l) &= ~VDIRT;
			vreopen(p, lineno(tp), l);
			p = LINE(l) + DEPTH(l);
		} else
			p += DEPTH(l);
		tp++;
	}

	/*
	 * That takes care of lines which were already partially displayed.
	 * Now try to fill the rest of the screen with text.
	 */
	if (state == VISUAL && p <= WBOT) {
		int ovcline = vcline;

		vcline = l;
		for (; tp <= dol && Peekkey != ATTN; tp++) {
			getline(*tp);
			if (p + vdepth() - 1 > WBOT)
				break;
			vopen(tp, p);
			p += DEPTH(vcline);
			vcline++;
		}
		vcline = ovcline;
	}

	/*
	 * Thats all the text we can get on.
	 * Now rest of lines (if any) get either a ~ if they
	 * are past end of file, or an @ if the next line won't fit.
	 */
	for (; p <= WBOT && Peekkey != ATTN; p++)			
		vclrlin(p, tp);
	strcLIN(temp);
	hold = oldhold;
	if (heldech)
		vclrech(0);
#ifdef ADEBUG
	if (trace)
		tvliny();
#endif
}
예제 #9
0
파일: ex_vops.c 프로젝트: chungy/ex-vi
/*
 * Open new lines.
 *
 * Tricky thing here is slowopen.  This causes display updating
 * to be held off so that 300 baud dumb terminals don't lose badly.
 * This also suppressed counts, which otherwise say how many blank
 * space to open up.  Counts are also suppressed on intelligent terminals.
 * Actually counts are obsoleted, since if your terminal is slow
 * you are better off with slowopen.
 */
void 
voOpen (
    int c,	/* mjm: char --> int */
    register int cnt
)
{
	register int ind = 0, i;
	short oldhold = hold;
#ifdef	SIGWINCH
	sigset_t set, oset;
#endif

	if (value(SLOWOPEN) || value(REDRAW) && AL && DL)
		cnt = 1;
#ifdef	SIGWINCH
	sigemptyset(&set);
	sigaddset(&set, SIGWINCH);
	sigprocmask(SIG_BLOCK, &set, &oset);
#endif
	vsave();
	setLAST();
	if (value(AUTOINDENT))
		ind = whitecnt(linebuf);
	if (c == 'O') {
		vcline--;
		dot--;
		if (dot > zero)
			getDOT();
	}
	if (value(AUTOINDENT)) {
#ifdef LISPCODE
		if (value(LISP))
			ind = lindent(dot + 1);
#endif
	}
	killU();
	prepapp();
	if (FIXUNDO)
		vundkind = VMANY;
	if (state != VISUAL)
		c = WBOT + 1;
	else {
		c = vcline < 0 ? WTOP - cnt : LINE(vcline) + DEPTH(vcline);
		if (c < ZERO)
			c = ZERO;
		i = LINE(vcline + 1) - c;
		if (i < cnt && c <= WBOT && (!AL || !DL))
			vinslin(c, cnt - i, vcline);
	}
	*genindent(ind) = 0;
	vdoappend(genbuf);
	vcline++;
	oldhold = hold;
	hold |= HOLDROL;
	vopen(dot, c);
	hold = oldhold;
	if (value(SLOWOPEN))
		/*
		 * Oh, so lazy!
		 */
		vscrap();
	else
		vsync1(LINE(vcline));
	cursor = linebuf;
	linebuf[0] = 0;
	vappend('o', 1, ind);
#ifdef	SIGWINCH
	sigprocmask(SIG_SETMASK, &oset, NULL);
#endif
}
예제 #10
0
파일: ex_vops.c 프로젝트: chungy/ex-vi
/*
 * Change operator.
 *
 * In a single line we mark the end of the changed area with '$'.
 * On multiple whole lines, we clear the lines first.
 * Across lines with both wcursor and wdot given, we delete
 * and sync then append (but one operation for undo).
 */
void 
vchange(int c)
{
	register char *cp;
	register int i, ind, cnt;
	line *addr;

	if (wdot) {
		/*
		 * Change/delete of lines or across line boundaries.
		 */
		if ((cnt = xdw()) < 0)
			return;
		getDOT();
		if (wcursor && cnt == 1) {
			/*
			 * Not really.
			 */
			wdot = 0;
			if (c == EOF) {
				vdelete(c);
				return;
			}
			goto smallchange;
		}
		if (cursor && wcursor) {
			/*
			 * Across line boundaries, but not
			 * necessarily whole lines.
			 * Construct what will be left.
			 */
			*cursor = 0;
			strcpy(genbuf, linebuf);
			getline(*wdot);
			if (strlen(genbuf) + strlen(wcursor) > LBSIZE - 2) {
				getDOT();
				beep();
				return;
			}
			strcat(genbuf, wcursor);
			if (c == EOF && *vpastwh(genbuf) == 0) {
				/*
				 * Although this is a delete
				 * spanning line boundaries, what
				 * would be left is all white space,
				 * so take it all away.
				 */
				wcursor = 0;
				getDOT();
				op = 0;
				notpart(lastreg);
				notpart('1');
				vdelete(c);
				return;
			}
			ind = -1;
		} else if (c == EOF && wcursor == 0) {
			vdelete(c);
			return;
		} else
#ifdef LISPCODE
			/*
			 * We are just substituting text for whole lines,
			 * so determine the first autoindent.
			 */
			if (value(LISP) && value(AUTOINDENT))
				ind = lindent(dot);
			else
#endif
				ind = whitecnt(linebuf);
		i = vcline >= 0 ? LINE(vcline) : WTOP;

		/*
		 * Delete the lines from the buffer,
		 * and remember how the partial stuff came about in
		 * case we are told to put.
		 */
		addr = dot;
		vremote(cnt, delete, 0);
		setpk();
		notenam = "delete";
		if (c != EOF)
			notenam = "change";
		/*
		 * If DEL[0] were nonzero, put would put it back
		 * rather than the deleted lines.
		 */
		DEL[0] = 0;
		if (cnt > 1)
			killU();

		/*
		 * Now hack the screen image coordination.
		 */
		vreplace(vcline, cnt, 0);
		wdot = NOLINE;
		noteit(0);
		vcline--;
		if (addr <= dol)
			dot--;

		/*
		 * If this is a across line delete/change,
		 * cursor stays where it is; just splice together the pieces
		 * of the new line.  Otherwise generate a autoindent
		 * after a S command.
		 */
		if (ind >= 0) {
			*genindent(ind) = 0;
			vdoappend(genbuf);
		} else {
			vmcurs = cursor;
			strcLIN(genbuf);
			vdoappend(linebuf);
		}

		/*
		 * Indicate a change on hardcopies by
		 * erasing the current line.
		 */
		if (c != EOF && state != VISUAL && state != HARDOPEN) {
			int oldhold = hold;

			hold |= HOLDAT, vclrlin(i, dot), hold = oldhold;
		}

		/*
		 * Open the line (logically) on the screen, and 
		 * update the screen tail.  Unless we are really a delete
		 * go off and gather up inserted characters.
		 */
		vcline++;
		if (vcline < 0)
			vcline = 0;
		vopen(dot, i);
		vsyncCL();
		noteit(1);
		if (c != EOF) {
			if (ind >= 0) {
				cursor = linebuf;
				linebuf[0] = 0;
				vfixcurs();
			} else {
				ind = 0;
				vcursat(cursor);
			}
			vappend('x', 1, ind);
			return;
		}
		if (*cursor == 0 && cursor > linebuf)
			cursor += skipleft(linebuf, cursor);
		vrepaint(cursor);
		return;
	}

smallchange:
	/*
	 * The rest of this is just low level hacking on changes
	 * of small numbers of characters.
	 */
	if (wcursor < linebuf)
		wcursor = linebuf;
	if (cursor == wcursor) {
		beep();
		return;
	}
	i = vdcMID();
	cp = cursor;
	if (state != HARDOPEN)
		vfixcurs();

	/*
	 * Put out the \\'s indicating changed text in hardcopy,
	 * or mark the end of the change with $ if not hardcopy.
	 */
	if (state == HARDOPEN) 
		bleep(i, cp);
	else {
		int	c, d, n;
		vcursbef(wcursor);
		d = skipleft(linebuf, wcursor);
		nextc(c, &wcursor[d], n);
		if (colsc(c) > 1)
			putchar(' ');
		putchar('$');
		i = cindent();
	}

	/*
	 * Remember the deleted text for possible put,
	 * and then prepare and execute the input portion of the change.
	 */
	cursor = cp;
	setDEL();
	CP(cursor, wcursor);
	if (state != HARDOPEN) {
		vcursaft(cursor - 1);
		doomed = i - cindent();
	} else {
/*
		sethard();
		wcursor = cursor;
		cursor = linebuf;
		vgoto(outline, value(NUMBER) << 3);
		vmove();
*/
		doomed = 0;
	}
	prepapp();
	vappend('c', 1, 0);
}
예제 #11
0
파일: ex_vops.c 프로젝트: chungy/ex-vi
void 
vundo (
    int show	/* if true update the screen */
)
{
	register int cnt;
	register line *addr;
	register char *cp;
	char *temp = smalloc(LBSIZE);
	bool savenote;
	int (*OO)(int);
	short oldhold = hold;

	switch (vundkind) {

	case VMANYINS:
		wcursor = 0;
		addr1 = undap1;
		addr2 = undap2 - 1;
		vsave();
		YANKreg('1');
		notecnt = 0;
		/* fall into ... */

	case VMANY:
	case VMCHNG:
		vsave();
		addr = dot - vcline;
		notecnt = 1;
		if (undkind == UNDPUT && undap1 == undap2) {
			beep();
			break;
		}
		/*
		 * Undo() call below basically replaces undap1 to undap2-1
		 * with dol through unddol-1.  Hack screen image to
		 * reflect this replacement.
		 */
		if (show)
			if (undkind == UNDMOVE)
				vdirty(0, TLINES);
			else
				vreplace(undap1 - addr, undap2 - undap1,
				    undkind == UNDPUT ? 0 : unddol - dol);
		savenote = notecnt;
		undo(1);
		if (show && (vundkind != VMCHNG || addr != dot))
			killU();
		vundkind = VMANY;
		cnt = dot - addr;
		if (cnt < 0 || cnt > vcnt || state != VISUAL) {
			if (show)
				vjumpto(dot, NOSTR, '.');
			break;
		}
		if (!savenote)
			notecnt = 0;
		if (show) {
			vcline = cnt;
			vrepaint(vmcurs);
		}
		vmcurs = 0;
		break;

	case VCHNG:
	case VCAPU:
		vundkind = VCHNG;
		CP(temp, vutmp);
		CP(vutmp, linebuf);
		doomed = column(vUA2 - 1) - column(vUA1 - 1);
		strcLIN(temp);
		cp = vUA1; vUA1 = vUD1; vUD1 = cp;
		cp = vUA2; vUA2 = vUD2; vUD2 = cp;
		if (!show)
			break;
		cursor = vUD1;
		if (state == HARDOPEN) {
			doomed = 0;
			vsave();
			vopen(dot, WBOT);
			vnline(cursor);
			break;
		}
		/*
		 * Pseudo insert command.
		 */
		vcursat(cursor);
		OO = Outchar; Outchar = vinschar; hold |= HOLDQIK;
		vprepins();
		temp[vUA2 - linebuf] = 0;
		for (cp = &temp[vUA1 - linebuf]; *cp;) {
			int	c, n;
			nextc(c, cp, n);
			cp += n;
			putchar(c);
		}
		Outchar = OO; hold = oldhold;
		endim();
		physdc(cindent(), cindent() + doomed);
		doomed = 0;
		vdirty(vcline, 1);
		vsyncCL();
		if (cursor > linebuf && cursor >= strend(linebuf))
			cursor += skipleft(linebuf, cursor);
		vfixcurs();
		break;

	case VNONE:
		beep();
		break;
	}
	free(temp);
}
예제 #12
0
파일: g_map.cpp 프로젝트: jder/verge3
// Overkill (2006-07-20): Saver functions!
void MAP::save(FILE *f)
{
	int i;
	char tempfn[16] = "$$v3map.tmp";
	FILE *out = fopen(tempfn, "wb");
	if (!out) err("Unable to open %s for writing!", tempfn);
	// Map signature.
	char signature[8];
	strcpy(signature, maptag);
	fwrite(&signature, 1, 6, f);

	// Version
	int version = MAP_VERSION;
	fwrite(&version, 1, 4, f);

	// USE OUTPUT BUFFER FROM THIS POINT ON.
	fwrite(mapname, 1, 256, out);
	//log("mapname: %s", mapname);
	// savevspname, not vspname because it's what the vsp file WILL be,
	// not necessarily what it IS at that moment.
	// So, you can set it then FileSaveVSP() down the line.
	fwrite(savevspname, 1, 256, out);
	//log("savevspname: %s", savevspname);
	fwrite(musicname, 1, 256, out);
	//log("musicname: %s", musicname);
	fwrite(renderstring, 1, 256, out);
	//log("renderstring: %s", renderstring);
	fwrite(startupscript, 1, 256, out);
	//log("startupscript: %s", startupscript);
	fwrite(&startx, 1, 2, out);
	fwrite(&starty, 1, 2, out);

	fwrite(&numlayers, 1, 4, out);
	for (i = 0; i < numlayers; i++)
	{
		layers[i]->save(out);
	}

	// Obs.
	cfwrite(obslayer, 1, mapwidth*mapheight, out);
	// Zones
	cfwrite(zonelayer, 1, mapwidth*mapheight*2, out);

	fwrite(&numzones, 1, 4, out);
	for (i=0; i<numzones; i++)
	{
		fwrite(zones[i]->name, 1, 256, out);
		fwrite(zones[i]->script, 1, 256, out);
		fwrite(&zones[i]->percent, 1, 1, out);
		fwrite(&zones[i]->delay, 1, 1, out);
		fwrite(&zones[i]->method, 1, 1, out);
	}

	// ENTITIES! <3.
	fwrite(&entities, 1, 4, out);
	for (i=0; i<entities; i++)
	{
		//log("ENT %d of %d", i, entities);
		// Tile coords.
		int x = entity[i]->x / 16;
		int y = entity[i]->y / 16;
		fwrite(&x, 1, 2, out);
		fwrite(&y, 1, 2, out);
		fwrite(&entity[i]->face, 1, 1, out);
		fwrite(&entity[i]->obstructable, 1, 1, out);
		fwrite(&entity[i]->obstruction, 1, 1, out);
		fwrite(&entity[i]->autoface, 1, 1, out);
		fwrite(&entity[i]->speed, 1, 2, out);
		//log("HERE?");
		// FIXME: ACTIVATION MODE
		int activationMode = 0;
		fwrite(&activationMode, 1, 1, out);
		// Movecode and wandering.
		fwrite(&entity[i]->movecode, 1, 1, out);
		fwrite(&entity[i]->wx1, 1, 2, out);
		fwrite(&entity[i]->wy1, 1, 2, out);
		fwrite(&entity[i]->wx2, 1, 2, out);
		fwrite(&entity[i]->wy2, 1, 2, out);
		fwrite(&entity[i]->wdelay, 1, 2, out);
		//log("YAR?");
		// Expand! whatever, man.
		int expand = 0;
		fwrite(&expand, 1, 4, out);

		// h8 u STD::string.
		char tempchar[256];

		//log("movestr: %s", entity[i]->movestr);
		fwrite(entity[i]->movestr, 1, 256, out);
		strcpy(tempchar, entity[i]->chr->name.c_str());
		fwrite(tempchar, 1, 256, out);
		strcpy(tempchar, entity[i]->description.c_str());
		fwrite(tempchar, 1, 256, out); // description
		strcpy(tempchar, entity[i]->script.c_str());
		fwrite(tempchar, 1, 256, out); // The actual script position.
	}
	// NO LONGER NEED TO USE THE OUTPUT BUFFER
	fclose(out);
	
	// Why vopen instead? I... don't know!
	// Now that we've finished the buffer though, we can
	// use this to fill in the unknown map information.
	
	VFILE *tmp = vopen(tempfn);
	if (!tmp) err("Could not open %s for reading!", tempfn);
	int bufferlength = filesize(tmp);
	byte* buf = new byte[bufferlength];
	vread(buf, bufferlength, tmp);
	vclose(tmp);
	// Delete the temporary buffer, we've gotten what we wanted.
	remove(tempfn);

	// Alright... finally, all this to get the offset for the VC stuffs.
	int vcofs = 14 + bufferlength;
	fwrite(&vcofs, 1, 4, f);
	// Write the buffer into the map now.
	fwrite(buf, 1, bufferlength, f);
	// VC funcs are waaay down here.
	int vcfuncs = 0; // number compiled should be none.
	//log("VCOFS: %d CURRENT POS: %d", vcofs, ftell(f));
	fwrite(&vcfuncs, 1, 4, f);
}
예제 #13
0
파일: g_map.cpp 프로젝트: jder/verge3
MAP::MAP(char *fname)
{
	VFILE *f = vopen(fname);
	if (!f)
		err("MAP::MAP() - could not load map %s", fname);

	strcpy(mapfname, fname);
	strlwr(mapfname);

	char signature[8];
	vread(signature, 6, f);
	if (strcmp(signature, maptag))
		err("MAP::MAP() - %s is not a valid mapfile!", fname);

	int version;
	vread(&version, 4, f);
	if (version != MAP_VERSION)
		err("MAP::MAP() - %s is not the correct MAP format version!", fname);
	vread(&version, 4, f); // skip vc offset

	vread(mapname, 256, f);
	vread(vspname, 256, f);
	strcpy(savevspname, vspname); // Overkill 2006-05-21
	vread(musicname, 256, f);
	vread(renderstring, 256, f);
	vread(startupscript, 256, f);

	PlayMusic(musicname);

	startx = starty = 0;
	vread(&startx, 2, f);
	vread(&starty, 2, f);

	std::string s = std::string(fname);
	int offs = s.rfind('\\');
	if (offs >= 0)
	{
		s.replace(offs+1,strlen(fname),vspname);
		tileset = new VSP((char *)s.c_str());
	}
	else
	{
		offs = s.rfind('/');
		if (offs >= 0)
		{
			s.replace(offs+1,strlen(fname),vspname);
			tileset = new VSP((char *)s.c_str());
		}
		else
			tileset = new VSP(vspname);
	}

	vread(&numlayers, 4, f);

	//layers = new Layer*[numlayers];
	layers.resize(numlayers);
	int i;
	for (i=0; i<numlayers; i++)
		layers[i] = new Layer(f);

	mapwidth = layers[0]->width;
	mapheight = layers[0]->height;

	obslayer = new byte[mapwidth*mapheight];
	zonelayer = new word[mapwidth*mapheight];
	cvread(obslayer, mapwidth*mapheight, f);
	cvread(zonelayer, mapwidth*mapheight*2, f);

	vread(&numzones, 4, f);
	zones.resize(numzones);
	for (i=0; i<numzones; i++)
	{
		zones[i] = new Zone;
		zones[i]->percent = zones[i]->method = zones[i]->delay = 0;
		vread(zones[i]->name, 256, f);
		vread(zones[i]->script, 256, f);
		vread(&zones[i]->percent, 1, f);
		vread(&zones[i]->delay, 1, f);
		vread(&zones[i]->method, 1, f);
	}

	vread(&mapentities, 4, f);

	for (i=0; i<mapentities; i++)
	{
		int t=0, x1=0, y1=0, x2=0, y2=0;
		char movescript[256], chrname[256], script[256], description[256];

		vread(&x1, 2, f);
		vread(&y1, 2, f);
		int o1 = vtell(f);
		vseek(f, 22, 1);
		vread(movescript, 256, f);
		vread(chrname, 256, f);
		vread(description, 256, f); // this is actually the description which we dont care about
		vread(script, 256, f); // this is the actual script
		vseek(f, o1, 0);

		int i = AllocateEntity(x1*16, y1*16, chrname);

		entity[i]->description = description;
		entity[i]->script = script;
		vread(&t, 1, f);
		if (!t) t = SOUTH;
		entity[i]->setface(t); t=0;
		vread(&t, 1, f);
		entity[i]->obstructable = t ? true : false; t=0;
		vread(&t, 1, f);
		entity[i]->obstruction = t ? true : false; t=0;
		vread(&t, 1, f);
		entity[i]->autoface = (t!=0); t=0;
		vread(&t, 2, f);
		entity[i]->setspeed(t); t=0;
		vread(&t, 1, f);
		// activation mode FIXME
		vread(&t, 1, f);

		vread(&x1, 2, f);
		vread(&y1, 2, f);
		vread(&x2, 2, f);
		vread(&y2, 2, f);
		switch(t)
		{
			case 0: entity[i]->SetMotionless(); break;
			case 1: entity[i]->SetWanderZone(); break;
			case 2: entity[i]->SetWanderBox(x1, y1, x2, y2); break; //FIXME
			case 3: entity[i]->SetMoveScript(movescript); break;
		}
		t=0; vread(&t, 2, f);
		entity[i]->SetWanderDelay(t);
		vread(&t, 4, f);
		vseek(f, 1024, 1);
		/*
		vread(&tlen, 4, f);
		vread(ename, tlen+1, f);
		// chr filename
		vread(&tlen, 4, f);
		vread(chrfn, tlen+1, f);
		// script
		vread(&tlen, 4, f);
		vread(escript, tlen+1, f);
		// movescript
		vread(&tlen, 4, f);
		vread(emovescript, tlen+1, f);

		vread(&tlen, 4, f);
		vread(&tlen, 4, f);
		int eface, speed, tx, ty;
		vread(&eface, 4, f);
		vread(&speed, 4, f);
		vread(&tx, 4, f);
		vread(&ty, 4, f);

		vread(&x1, 4, f);
		vread(&y1, 4, f);
		vread(&x2, 4, f);
		vread(&y2, 4, f);

		int idx = AllocateEntity(tx*16, ty*16, chrfn);
		entity[idx]->setface(eface);
		entity[idx]->setspeed(speed);
		entity[idx]->script = escript;
		entity[idx]->autoface = (eflags & ENT_AUTOFACE) ? true : false;
		entity[idx]->obstructable = (eflags & ENT_OBSTRUCTED) ? true : false;
		entity[idx]->obstruction = (eflags & ENT_OBSTRUCTS) ? true : false;

		if (method == ENT_MOVESCRIPT) entity[idx]->SetMoveScript(emovescript);
		if (method == ENT_WANDERZONE) entity[idx]->SetWanderZone();
		if (method == ENT_WANDERBOX) entity[idx]->SetWanderBox(x1, y1, x2, y2);*/
	}
	current_map = this;
	se->LoadMapScript(f, mapfname);
	vclose(f);
	se->ExecuteFunctionString(startupscript);
}
예제 #14
0
// Build and pop up a buffer containing a list of all screens and their associated buffers.  Render buffer and return status.
int showScreens(Value *rp,int n) {
	Buffer *slistp;
	EScreen *scrp;			// Pointer to current screen to list.
	EWindow *winp;			// Pointer into current screens window list.
	uint wnum;
	StrList rpt;
	int windcol = 7;
	int filecol = 37;
	char *strp,wkbuf[filecol + 16];

	// Get a buffer and open a string list.
	if(sysbuf(text160,&slistp) != SUCCESS)
			// "Screens"
		return rc.status;
	if(vopen(&rpt,NULL,false) != 0)
		return vrcset();

	// Construct the header lines.
	if(vputs(text89,&rpt) != 0 || vputc('\n',&rpt) != 0 ||
	    // "Screen Window      Buffer                File"
	 vputs("------ ------  --------------------  -------------------------------",&rpt) != 0)
		return vrcset();

	// For all screens...
	scrp = sheadp;
	do {
		// Store the screen number.
		sprintf(wkbuf,"\n%4hu   ",scrp->s_num);
		strp = strchr(wkbuf,'\0');

		// List screen's window numbers and buffer names.
		wnum = 0;
		winp = scrp->s_wheadp;
		do {
			Buffer *bufp = winp->w_bufp;

			// Indent if not first time through.
			if(wnum != 0) {
				wkbuf[0] = '\n';
				strp = wkbuf + 1;
				do {
					*strp++ = ' ';
					} while(strp <= wkbuf + windcol);
				}

			// Store window number, buffer name, and filename.
			sprintf(strp,"%4u   %c%s",++wnum,(bufp->b_flags & BFCHGD) ? '*' : ' ',bufp->b_bname);
			strp = strchr(strp,'\0');
			if(bufp->b_fname != NULL)			// Pad if filename exists.
				do {
					*strp++ = ' ';
					} while(strp <= wkbuf + filecol);
			*strp = '\0';					// Save buffer and add filename.
			if(vputs(wkbuf,&rpt) != 0 ||
			 (bufp->b_fname != NULL && vputs(bufp->b_fname,&rpt) != 0))
				return vrcset();

			// On to the next window.
			} while((winp = winp->w_nextp) != NULL);

		// On to the next screen.
		} while((scrp = scrp->s_nextp) != NULL);

	// Add the results to the buffer.
	if(vclose(&rpt) != 0)
		return vrcset();
	if(bappend(slistp,rpt.sl_vp->v_strp) != SUCCESS)
		return rc.status;

	// Display results.
	return render(rp,n < 0 ? -2 : n,slistp,RENDRESET | (n != INT_MIN && n < -1 ? RENDALTML : 0));
	}
예제 #15
0
void
vappend(int ch, int cnt, int indent)
{
	int i;
	unsigned char *gcursor;
	bool escape;
	int repcnt, savedoomed;
	short oldhold = hold;
	int savecnt = cnt;
	line *startsrcline;
	int startsrccol, endsrccol;
	int gotNL = 0;
	int imultlinecnt = 0;
	int omultlinecnt = 0;

	if ((savecnt > 1) && (ch == 'o' || ch == 'O')) {
		omultlinecnt = 1;
	}
#ifdef XPG6
	if ((savecnt > 1) && (ch == 'a' || ch == 'A' || ch == 'i' || ch == 'I'))
		imultlinecnt = 1;
#endif /* XPG6 */

	/*
	 * Before a move in hardopen when the line is dirty
	 * or we are in the middle of the printed representation,
	 * we retype the line to the left of the cursor so the
	 * insert looks clean.
	 */

	if (ch != 'o' && state == HARDOPEN && (rubble || !ateopr())) {
		rubble = 1;
		gcursor = cursor;
		i = *gcursor;
		*gcursor = ' ';
		wcursor = gcursor;
		(void) vmove();
		*gcursor = i;
	}
	/*
	 * If vrep() passed indent = 0, this is the 'r' command,
	 * so don't autoindent until the last char.
	 */
	vaifirst = indent == 0;

	/*
	 * Handle replace character by (eventually)
	 * limiting the number of input characters allowed
	 * in the vgetline routine.
	 */
	if (ch == 'r')
		repcnt = 2;
	else
		repcnt = 0;

	/*
	 * If an autoindent is specified, then
	 * generate a mixture of blanks to tabs to implement
	 * it and place the cursor after the indent.
	 * Text read by the vgetline routine will be placed in genbuf,
	 * so the indent is generated there.
	 */
	if (value(vi_AUTOINDENT) && indent != 0) {
		unsigned char x;
		gcursor = genindent(indent);
		*gcursor = 0;
		vgotoCL(nqcolumn(lastchr(linebuf, cursor), genbuf)); 
	} else {
		gcursor = genbuf;
		*gcursor = 0;
		if (ch == 'o')
			vfixcurs();
	}

	/*
	 * Prepare for undo.  Pointers delimit inserted portion of line.
	 */
	vUA1 = vUA2 = cursor;

	/*
	 * If we are not in a repeated command and a ^@ comes in
	 * then this means the previous inserted text.
	 * If there is none or it was too long to be saved,
	 * then beep() and also arrange to undo any damage done
	 * so far (e.g. if we are a change.)
	 */
	switch (ch) {
	case 'r':
		break;
	case 'a':
		/*
		 * TRANSLATION_NOTE
		 *	"A" is a terse mode message corresponding to
		 *	"APPEND MODE".
		 *	Translated message of "A" must be 1 character (not byte).
		 *	Or, just leave it.
		 */
		if (value(vi_TERSE)) {
			vshowmode(gettext("A"));
		} else {
			vshowmode(gettext("APPEND MODE"));
		}
		break;
	case 's':
		/*
		 * TRANSLATION_NOTE
		 *	"S" is a terse mode message corresponding to
		 *	"SUBSTITUTE MODE".
		 *	Translated message of "S" must be 1 character (not byte).
		 *	Or, just leave it.
		 */
		if (value(vi_TERSE)) {
			vshowmode(gettext("S"));
		} else {
			vshowmode(gettext("SUBSTITUTE MODE"));
		}
		break;
	case 'c':
		/*
		 * TRANSLATION_NOTE
		 *	"C" is a terse mode message corresponding to
		 *	"CHANGE MODE".
		 *	Translated message of "C" must be 1 character (not byte).
		 *	Or, just leave it.
		 */
		if (value(vi_TERSE)) {
			vshowmode(gettext("C"));
		} else {
			vshowmode(gettext("CHANGE MODE"));
		}
		break;
	case 'R':
		/*
		 * TRANSLATION_NOTE
		 *	"R" is a terse mode message corresponding to
		 *	"REPLACE MODE".
		 *	Translated message of "R" must be 1 character (not byte).
		 *	Or, just leave it.
		 */
		if (value(vi_TERSE)) {
			vshowmode(gettext("R"));
		} else {
			vshowmode(gettext("REPLACE MODE"));
		}
		break;
	case 'o':
		/*
		 * TRANSLATION_NOTE
		 *	"O" is a terse mode message corresponding to
		 *	"OPEN MODE".
		 *	Translated message of "O" must be 1 character (not byte).
		 *	Or, just leave it.
		 */
		if (value(vi_TERSE)) {
			vshowmode(gettext("O"));
		} else {
			vshowmode(gettext("OPEN MODE"));
		}
		break;
	case 'i':
		/*
		 * TRANSLATION_NOTE
		 *	"I" is a terse mode message corresponding to
		 *	"INSERT MODE" and the following "INPUT MODE".
		 *	Translated message of "I" must be 1 character (not byte).
		 *	Or, just leave it.
		 */
		if (value(vi_TERSE)) {
			vshowmode(gettext("I"));
		} else {
			vshowmode(gettext("INSERT MODE"));
		}
		break;
	default:
		/*
		 * TRANSLATION_NOTE
		 *	"I" is a terse mode message corresponding to
		 *	"INPUT MODE" and the previous "INSERT MODE".
		 *	Translated message of "I" must be 1 character (not byte).
		 *	Or, just leave it.
		 */
		if (value(vi_TERSE)) {
			vshowmode(gettext("I"));
		} else {
			vshowmode(gettext("INPUT MODE"));
		}
	}
	ixlatctl(1);
	if ((vglobp && *vglobp == 0) || peekbr()) {
		if (INS[128] == 0200) {
			(void) beep();
			if (!splitw)
				ungetkey('u');
			doomed = 0;
			hold = oldhold;
			return;
		}
		/*
		 * Unread input from INS.
		 * An escape will be generated at end of string.
		 * Hold off n^^2 type update on dumb terminals.
		 */
		vglobp = INS;
		inscdcnt = INSCDCNT;
		hold |= HOLDQIK;
	} else if (vglobp == 0) {
		/*
		 * Not a repeated command, get
		 * a new inserted text for repeat.
		 */
		INS[0] = 0;
		INS[128] = 0;
		INSCDCNT = 0;
	}

	/*
	 * For wrapmargin to hack away second space after a '.'
	 * when the first space caused a line break we keep
	 * track that this happened in gobblebl, which says
	 * to gobble up a blank silently.
	 */
	gobblebl = 0;

	startsrcline = dot;
	startsrccol = cursor - linebuf;

	/*
	 * Text gathering loop.
	 * New text goes into genbuf starting at gcursor.
	 * cursor preserves place in linebuf where text will eventually go.
	 */
	if (*cursor == 0 || state == CRTOPEN)
		hold |= HOLDROL;
	for (;;) {
		if (ch == 'r' && repcnt == 0)
			escape = 0;
		else {
			ixlatctl(1);
			/*
			 * When vgetline() returns, gcursor is
			 * pointing to '\0' and vgetline() has
			 * read an ESCAPE or NL.
			 */
			gcursor = vgetline(repcnt, gcursor, &escape, ch);
			if (escape == '\n') {
				gotNL = 1;
#ifdef XPG6
				if (ch == 'r') {
					/*
					 * XPG6 assertion 313 [count]r\n :
					 * Arrange to set cursor correctly.
					 */
					endsrccol = gcursor - genbuf - 1;
				}
#endif /* XPG6 */
			} else {
				/*
				 * Upon escape, gcursor is pointing to '\0'
				 * terminating the string in genbuf.
				 */
				endsrccol = gcursor - genbuf - 1;
			}
			ixlatctl(0);

			/*
			 * After an append, stick information
			 * about the ^D's and ^^D's and 0^D's in
			 * the repeated text buffer so repeated
			 * inserts of stuff indented with ^D as backtab's
			 * can work.
			 */
			if (HADUP)
				addtext("^");
			else if (HADZERO)
				addtext("0");
			if(!vglobp)
				INSCDCNT = CDCNT;
			while (CDCNT > 0) {
				addtext("\004");
				CDCNT--;
			}
			if (gobbled)
				addtext(" ");
			addtext(ogcursor);
		}
		repcnt = 0;

		/*
		 * Smash the generated and preexisting indents together
		 * and generate one cleanly made out of tabs and spaces
		 * if we are using autoindent and this isn't 'r' command.
		 */
		if (!vaifirst && value(vi_AUTOINDENT)) {
			i = fixindent(indent);
			if (!HADUP)
				indent = i;
			gcursor = strend(genbuf);
		}

		/*
		 * Set cnt to 1 to avoid repeating the text on the same line.
		 * Do this for commands 'i', 'I', 'a', and 'A', if we're
		 * inserting anything with a newline for XPG6.  Always do this
		 * for commands 'o' and 'O'.
		 */
		if ((imultlinecnt && gotNL) || omultlinecnt) {
			cnt = 1;
		}

		/*
		 * Limit the repetition count based on maximum
		 * possible line length; do output implied
		 * by further count (> 1) and cons up the new line
		 * in linebuf.
		 */
		cnt = vmaxrep(ch, cnt);
		/*
		 * cursor points to linebuf
		 * Copy remaining old text (cursor) in original
		 * line to after new text (gcursor + 1) in genbuf.
		 */
		CP(gcursor + 1, cursor);
		/*
		 * For [count] r \n command, when replacing [count] chars
		 * with '\n', this loop replaces [count] chars with "".
		 */
		do {
			/* cp new text (genbuf) into linebuf (cursor) */
			CP(cursor, genbuf);
			if (cnt > 1) {
				int oldhold = hold;

				Outchar = vinschar;
				hold |= HOLDQIK;
				viprintf("%s", genbuf);
				hold = oldhold;
				Outchar = vputchar;
			}
			/* point cursor after new text in linebuf */
			cursor += gcursor - genbuf;
		} while (--cnt > 0);
		endim();
		vUA2 = cursor;
		/* add the remaining old text after the cursor */
		if (escape != '\n')
			CP(cursor, gcursor + 1);

		/*
		 * If doomed characters remain, clobber them,
		 * and reopen the line to get the display exact.
		 * eg. c$ to change to end of line
		 */
		if (state != HARDOPEN) {
			DEPTH(vcline) = 0;
			savedoomed = doomed;
			if (doomed > 0) {
				int cind = cindent();

				physdc(cind, cind + doomed);
				doomed = 0;
			}
			if(MB_CUR_MAX > 1)
				rewrite = _ON;
			i = vreopen(LINE(vcline), lineDOT(), vcline);
			if(MB_CUR_MAX > 1)
				rewrite = _OFF;
#ifdef TRACE
			if (trace)
				fprintf(trace, "restoring doomed from %d to %d\n", doomed, savedoomed);
#endif
			if (ch == 'R')
				doomed = savedoomed;
		}

		/*
		 * Unless we are continuing on to another line
		 * (got a NL), break out of the for loop (got
		 * an ESCAPE).
		 */
		if (escape != '\n') {
			vshowmode("");
			break;
		}

		/*
		 * Set up for the new line.
		 * First save the current line, then construct a new
		 * first image for the continuation line consisting
		 * of any new autoindent plus the pushed ahead text.
		 */
		killU();
		addtext(gobblebl ? " " : "\n");
		/* save vutmp (for undo state) into temp file */
		vsave();
		cnt = 1;
		if (value(vi_AUTOINDENT)) {
			if (value(vi_LISP))
				indent = lindent(dot + 1);
			else
			     if (!HADUP && vaifirst)
				indent = whitecnt(linebuf);
			vaifirst = 0;
			strcLIN(vpastwh(gcursor + 1));
			gcursor = genindent(indent);
			*gcursor = 0;
			if (gcursor + strlen(linebuf) > &genbuf[LBSIZE - 2])
				gcursor = genbuf;
			CP(gcursor, linebuf);
		} else {
			/*
			 * Put gcursor at start of genbuf to wipe
			 * out previous line in preparation for
			 * the next vgetline() loop.
			 */
			CP(genbuf, gcursor + 1);
			gcursor = genbuf;
		}

		/*
		 * If we started out as a single line operation and are now
		 * turning into a multi-line change, then we had better yank
		 * out dot before it changes so that undo will work
		 * correctly later.
		 */
		if (FIXUNDO && vundkind == VCHNG) {
			vremote(1, yank, 0);
			undap1--;
		}

		/*
		 * Now do the append of the new line in the buffer,
		 * and update the display, ie: append genbuf to
		 * the file after dot.  If slowopen
		 * we don't do very much.
		 */
		vdoappend(genbuf);
		vundkind = VMANYINS;
		vcline++;
		if (state != VISUAL)
			vshow(dot, NOLINE);
		else {
			i += LINE(vcline - 1);
			vopen(dot, i);
			if (value(vi_SLOWOPEN))
				vscrap();
			else
				vsync1(LINE(vcline));
		}
		switch (ch) {
		case 'r':
			break;
		case 'a':
			if (value(vi_TERSE)) {
				vshowmode(gettext("A"));
			} else {
				vshowmode(gettext("APPEND MODE"));
			}
			break;
		case 's':
			if (value(vi_TERSE)) {
				vshowmode(gettext("S"));
			} else {
				vshowmode(gettext("SUBSTITUTE MODE"));
			}
			break;
		case 'c':
			if (value(vi_TERSE)) {
				vshowmode(gettext("C"));
			} else {
				vshowmode(gettext("CHANGE MODE"));
			}
			break;
		case 'R':
			if (value(vi_TERSE)) {
				vshowmode(gettext("R"));
			} else {
				vshowmode(gettext("REPLACE MODE"));
			}
			break;
		case 'i':
			if (value(vi_TERSE)) {
				vshowmode(gettext("I"));
			} else {
				vshowmode(gettext("INSERT MODE"));
			}
			break;
		case 'o':
			if (value(vi_TERSE)) {
				vshowmode(gettext("O"));
			} else {
				vshowmode(gettext("OPEN MODE"));
			}
			break;
		default:
			if (value(vi_TERSE)) {
				vshowmode(gettext("I"));
			} else {
				vshowmode(gettext("INPUT MODE"));
			}
		}
		strcLIN(gcursor);
		/* zero genbuf */
		*gcursor = 0;
		cursor = linebuf;
		vgotoCL(nqcolumn(cursor - 1, genbuf));
	} /* end for (;;) loop in vappend() */

	if (imultlinecnt && gotNL) {
		imultlinerep(savecnt, startsrcline, startsrccol, endsrccol);
	} else if (omultlinecnt) {
		omultlinerep(savecnt, startsrcline, endsrccol);
#ifdef XPG6
	} else if (savecnt > 1 && ch == 'r' && gotNL) {
		/*
		 * XPG6 assertion 313 & 254 : Position cursor for [count]r\n
		 * then insert [count -1] newlines.
		 */
		endsrccol = gcursor - genbuf - 1;
		rmultlinerep(savecnt, endsrccol);
#endif /* XPG6 */
	}

	/*
	 * All done with insertion, position the cursor
	 * and sync the screen.
	 */
	hold = oldhold;
	if ((imultlinecnt && gotNL) || omultlinecnt) {
		fixdisplay();
#ifdef XPG6
	} else if (savecnt > 1 && ch == 'r' && gotNL) {
		fixdisplay();
		/*
		 * XPG6 assertion 313 & 254 [count]r\n : Set flag to call
		 * fixdisplay() after operate() has finished.  To be sure that
		 * the text (after the last \n followed by an indent) is always
		 * displayed, fixdisplay() is called right before getting
		 * the next command.
		 */
		redisplay = 1;
#endif /* XPG6 */
	} else if (cursor > linebuf) {
		cursor = lastchr(linebuf, cursor);
#ifdef XPG6
		/*
		 * XPG6 assertion 313 & 254 [count]r\n :
		 * For 'r' command, when the replacement char causes new
		 * lines to be created, point cursor to first non-blank.
		 * The old code, ie: cursor = lastchr(linebuf, cursor);
		 * set cursor to the blank before the first non-blank
		 * for r\n
		 */
		if (ch == 'r' && gotNL && isblank((int)*cursor))
			++cursor;
#endif /* XPG6 */
	}
	if (state != HARDOPEN)
		vsyncCL();
	else if (cursor > linebuf)
		back1();
	doomed = 0;
	wcursor = cursor;
	(void) vmove();
}
예제 #16
0
// Display a pop-up window and page it for the user.  If altmodeline is true, display buffer name and filename (only) on bottom
// mode line.  If endprompt is true, wait for user to press a key before returning (regardless of page size).  Current bindings
// (if any) for backPage, forwPage, backLine, and forwLine commands are recognized as well as 'b' (backward page), 'f' or space
// (forward page), 'u' (backward half page), 'd' (forward half page), 'g' (goto first page), 'G' (goto last page), ESC or 'q'
// (exit), and '?' (help).  Any non-navigation key gets pushed back into the input stream to be interpeted later as a command. 
// Return status.
int bpop(Buffer *bufp,bool altmodeline,bool endprompt) {
	Line *lnp1,*lnp,*lpmax;
	int crow;		// Current screen row number.
	int disprows;		// Total number of display rows.
	int halfpage;		// Rows in a half page.
	int n;			// Rows to move.
	ushort ek;		// Input extended key.
	char *strp,*strpz;	// Line text pointers.
	char *hprompt = NULL;	// Help prompt;
	bool firstpass = true;

	// Display special mode line if requested.
	if(altmodeline) {

		// Find last window on screen and rewrite its mode line.
		wupd_modeline(wnextis(NULL),bufp);
		}

	// Set up and display a pop-up "window".
	disprows = term.t_nrow - 2;

	// Check if buffer will fit on one page and if not, set lpmax to first line of last page.
	lpmax = NULL;
	n = 0;
	for(lnp = lforw(bufp->b_hdrlnp); lnp != bufp->b_hdrlnp; lnp = lforw(lnp)) {
		if(++n > disprows) {

			// Find beginning of last page.
			lpmax = bufp->b_hdrlnp;
			n = disprows;
			do {
				lpmax = lback(lpmax);
				} while(--n > 0);
			break;
			}
		}

	// Begin at the beginning.
	lnp1 = lforw(bufp->b_hdrlnp);
	halfpage = disprows / 2;
	n = 0;

	// Display a page (beginning at line lnp1 + n) and prompt for a naviagtion command.  Loop until exit key entered or
	// endprompt is false and buffer fits on one page (lpmax is NULL).
	for(;;) {
		lnp = lnp1;

		// Moving backward?
		if(n < 0) {
			do {
				// At beginning of buffer?
				if(lpmax == NULL || lnp1 == lforw(bufp->b_hdrlnp))
					break;

				// No, back up one line.
				lnp1 = lback(lnp1);
				} while(++n < 0);
			}

		// Moving forward?
		else if(n > 0) {
			do {
				// At end of buffer or max line?
				if(lpmax == NULL || lnp1 == bufp->b_hdrlnp || lnp1 == lpmax)
					break;

				// No, move forward one line.
				lnp1 = lforw(lnp1);
				} while(--n > 0);
			}

		// Illegal command?
		if(n != 0 && lnp1 == lnp)

			// Yes, ignore it.
			n = 0;
		else {
			// Found first row ... display page.
			lnp = lnp1;
			crow = 0;
			do {
				// At end of buffer?
				if(lnp == bufp->b_hdrlnp) {

					// Yes, erase remaining lines on physical screen.
					while(crow < disprows) {
						vtmove(crow,0);
						vteeol();
#if COLOR
						vscreen[crow]->v_rfcolor = gfcolor;
						vscreen[crow]->v_rbcolor = gbcolor;
#endif
						vscreen[crow]->v_left = FARRIGHT;
						vscreen[crow]->v_right = 0;
#if COLOR
						vscreen[crow++]->v_flags |= VFCHGD | VFCOLOR;
#else
						vscreen[crow++]->v_flags |= VFCHGD;
#endif
						}
					break;
					}

				// Update the virtual screen image for this line.  Characters past right edge of screen won't be
				// displayed, so ignore those.
				vtmove(crow,0);
				strpz = (strp = ltext(lnp)) + (lused(lnp) <= (int) term.t_ncol ? lused(lnp) : term.t_ncol);
				while(strp < strpz)
					vtputc(*strp++);
				vteeol();
#if COLOR
				vscreen[crow]->v_rfcolor = gfcolor;
				vscreen[crow]->v_rbcolor = gbcolor;
#endif
				vscreen[crow]->v_left = FARRIGHT;
				vscreen[crow]->v_right = 0;
#if COLOR
				vscreen[crow++]->v_flags |= VFCHGD | VFCOLOR;
#else
				vscreen[crow++]->v_flags |= VFCHGD;
#endif
				// On to the next line.
				lnp = lforw(lnp);
				} while(crow < disprows);

			// Screen is full.  Copy the virtual screen to the physical screen.
			if(pupd_all(false) != SUCCESS)
				return rc.status;

			// Bail out if called from terminp() and one-page buffer.
			if(firstpass && !endprompt && lpmax == NULL)
				goto uexit;
			firstpass = false;
			}

		// Display prompt.
		mlputs(MLHOME | MLFORCE,hprompt != NULL ? hprompt : lpmax == NULL || lnp1 == lpmax ? text201 : ": ");
													// "End: "
		if(TTflush() != SUCCESS)
			return rc.status;

		// Get response.
		for(;;) {
			// Get a keystroke and decode it.
			if(getkey(&ek) != SUCCESS)
				return rc.status;

			// Exit?
			if(ek == (CTRL | '[') || ek == 'q')
				goto uexit;

			// Forward whole page?
			if(ek == ' ' || ek == 'f' || iscmd(ek,forwPage)) {
				n = disprows - overlap;
				break;
				}

			// Forward half page?
			if(ek == 'd') {
				n = halfpage;
				break;
				}

			// Backward whole page?
			if(ek == 'b' || iscmd(ek,backPage)) {
				n = overlap - disprows;
				break;
				}

			// Backward half page?
			if(ek == 'u') {
				n = -halfpage;
				break;
				}

			// Forward a line?
			if(iscmd(ek,forwLine)) {
				n = 1;
				break;
				}

			// Backward a line?
			if(iscmd(ek,backLine)) {
				n = -1;
				break;
				}

			// First page?
			if(ek == 'g') {
				if(lpmax == NULL || lnp1 == lforw(bufp->b_hdrlnp))
					n = -1;			// Force beep.
				else {
					lnp1 = lforw(bufp->b_hdrlnp);
					n = 0;
					}
				break;
				}

			// Last page?
			if(ek == 'G') {
				if(lpmax == NULL || lnp1 == lpmax)
					n = 1;			// Force beep.
				else {
					lnp1 = lpmax;
					n = 0;
					}
				break;
				}

			// Help?
			if(ek == '?') {
				StrList msg;

				// Get string list...
				if(vopen(&msg,NULL,false) != 0)
					return vrcset();

				// build prompt...
				if(vputs(text202,&msg) != 0)
						// "(<SPC>,f"
					return vrcset();
				if(hkey(&msg,forwPage,0) != SUCCESS)
					return rc.status;
				if(vputs(text203,&msg) != 0)
						// ") +page (b"
					return vrcset();
				if(hkey(&msg,backPage,0) != SUCCESS)
					return rc.status;
				if(vputs(text204,&msg) != 0)
						// ") -page (d) +half (u) -half"
					return vrcset();
				if(hkey(&msg,forwLine,'+') != SUCCESS || hkey(&msg,backLine,'-') != SUCCESS)
					return rc.status;
				if(vputs(text206,&msg) != 0)
						// " (g) first (G) last (ESC,q) quit (?) help: "
					return vrcset();

				// and display it.
				if(vclose(&msg) != 0)
					return vrcset();
				mlputs(MLHOME | MLFORCE,msg.sl_vp->v_strp);
				}
			else {
				// Other key.  "Unget" the key for reprocessing and return.
				tungetc(ek);
				goto uexit;
				}
			}
		}
uexit:
	uphard();
	if(endprompt)
		mlerase(MLFORCE);

	return rc.status;
	}