📄 tty.cpp
字号:
for(i = idx, j = idx + nCols - (idx % nCols); i < j; i++) pVmem[i] = ' '; GfxRect(xcurr,ycurr,x+dx,ycurr+GfxTextHeight(),GFX_Fill,nBgnd); break; case 'm': // <------------------- Set Graphics Mode (Fg/Bg Colors) if (nEscape >= 4) while (n1 >= 30) { if ((j = n1 % 10) <= 7) { if (3 == (n1 / 10)) nFgnd = aColor[j]; if (4 == (n1 / 10)) nBgnd = aColor[j]; } n1 = n2, n2 = 0; } break; case 's': // <---------------------- save current cursor position jdx = idx; break; case 'u': // <---------------------------- restore cursor position idx = jdx; ycurr = y + ddy + (GfxTextHeight() * idx / nCols); ch = pVmem[idx], pVmem[idx] = '\0'; xcurr = x + XM + GfxTextExtent(pVmem + idx - (idx % nCols)); pVmem[idx] = ch; break; case ';': // <------------------------- process argument separator return (nEscape + 1); default: (nEscape > 2) ? (n2 = (INT16)ch) : (n1 = (INT16)ch); return (nEscape + 1); } } return 0;}/////////////////// Copy the passed data into the screen buffer, interpreting any special// characters as we go. If the display is "visible", echo the changes to// the screen - I'd like a better Bell routine, though. The unusual amount// of code in the routines that set the horizontal pixel var <xcurr> is to// accomodate proportional fonts (Microsoft - looks good, by costs!)//// CAUTION! The Auto Line-feed mode relies on the ACR case falling// through to the ALF case.. don't change the order!//void tty::Display (char *cp, INT16 n){ if (nMode & TTY_Active) { Mickey.AutoPointer(x, y, x+dx, y+dy); TtyCursor(OFF); GfxSetClip(x, y, x+dx, y+dy); } while (n--) if (nEscape) { nEscape = AnsiDriver(*cp++); continue; } else { switch (*cp) { case ABEL: fputc('\a', stdout); break; case BKSP: if (idx) { --idx; char cTemp = pVmem[idx]; pVmem[idx] = '\0'; if (((idx % nCols) == (nCols - 1)) && (ycurr > y + ddy)) ycurr -= GfxTextHeight(); xcurr = x + GfxTextExtent(pVmem + idx - (idx % nCols)) + XM; pVmem[idx] = cTemp; } break; case AFF : Reset(FALSE); break; case ACR: xcurr = x+XM; idx -= idx % nCols; if (0 == (nMode & TTY_AutoLF)) break; case ALF: if (idx >= nCols * (nRows - 1)) Scroll(); else { idx += nCols; ycurr += GfxTextHeight(); } break; case ESC: if (nMode & TTY_UseANSI) nEscape = 1; break; default: if ((*cp >= ' ') && (*cp < DEL)) { pVmem[idx++] = *cp; char cTemp = pVmem[idx]; pVmem[idx] = '\0'; if (nMode & TTY_Active) { GfxTextColor(nFgnd); GfxText(xcurr, ycurr, pVmem+idx-1, GFX_Transparent); } if (idx % nCols) { xcurr += GfxTextExtent(pVmem+idx-1); pVmem[idx] = cTemp; } else { xcurr = x + XM; if (idx / nCols < nRows) { ycurr += GfxTextHeight(); pVmem[idx] = cTemp; } else { Scroll(); idx = nCols * (nRows - 1); } } } } // end switch ++cp; } // end while if (nMode & TTY_Active) { TtyCursor(ON); GfxClrClip(); Mickey.ShowPointer(); }}////////////////////// Scroll the video RAM, filling the last line with blanks and scroll the// visible screen too, if it is active. Again, scrolling would probably// run faster if the "video RAM" buffer used a start-of-scan pointer, but// the arrays should be small and I'm running out of time...//// YABBWA .. Yet another Borland Bug Work-Around!// The Borland farmalloc/farfree functions eventually fail, resulting// in no scroll. Since this is un-acceptable, we'll do a character// based scroll if (when) IMALLOC returns NULL. Needless to say, the// Microsoft C/C++ 7.00 runs with no problem. jeeze.// ** News Flash: this probably due to Borland's delete not operating// ** like Microsoft's .. could be fixed now - need testing (18-MAY-93).//void tty::Scroll (void){ INT16 nLastLine = nCols * (nRows - 1), x2 = x+dx, y0 = y+ddy; memcpy(pVmem, pVmem+nCols, nLastLine); memset(pVmem+nLastLine, ' ', nCols); if (nMode & TTY_Active) { PIMBUF pImg = GfxGetImage(x, y0+GfxTextHeight(), x2, y+dy); if (pImg) { GfxPutImage(x, y0, pImg); GfxFreeImage(pImg); } else { char *cp, *pBuf = new char[nCols+1]; if (NULL == pBuf) DevError(42, FATAL); else { for (INT16 i = 0, j = nCols; i < nRows; i++, j += nCols) { GfxRect(x, y0, x2, y0+GfxTextHeight(), GFX_Fill, nBgnd); strncpy(pBuf, pVmem+j, nCols); cp = pBuf + nCols - 1; while ((*cp == ' ') && (cp >= pBuf)) --cp; *(cp+1) = '\0'; if (*pBuf) GfxText(x+XM, y0, pBuf, GFX_Transparent); y0 += GfxTextHeight(); } DELETE_ARRAY pBuf; } } GfxRect(x, y0+(GfxTextHeight()*(nRows-1)), x2, y+dy, GFX_Fill, nBgnd); }}//////////////////////// Routine controls processing of characters read from keyboard.// If there an outstanding request for data, service it immediatly// Otherwise add the key to the ring buffer. The char is written// to video RAM (and perhaps displayed) if terminal is set to Simplex.//void tty::PutKey (char ch){ if (nMode & TTY_Simplex) Display(&ch, 1); RngBuf.RngPut(ch); if (uCnt) { --uCnt; MSG msg(uID, KM_Read, (UINT16)RngBuf.RngGet()); pTx->PostMsg(uDest, &msg); }}//////////////////////// Service a request for key data. Several things should never happen,// but let's be defensive.. First, we should be "open" and the request// must have come from whoever has us open. Next, characters can only// be sent if we happen to have any, otherwise we increment a request-for-// data count and exit (this count will be inspected when data finally// arrives). If we have data we either place it in the requesting message// struct if the transfer was synchronous, or post a message if the request// was async.//// ASIDE: I'm not all that keen on this one character per message scheme// It will probably bog down - a more flexible arrangement like a Block// mode request may ultimately be a better way to fly.. END OF ASIDE.//void tty::GetKey (PMSG pM){ if (RngBuf.RngStat() == FALSE) ++uCnt; else { char ch = RngBuf.RngGet(); if (IS_SYNCH(pM->wMsgType)) pM->wParam = (UINT16)ch; else { MSG msg(uID, KM_Read, (UINT16)ch); pTx->PostMsg(uDest, &msg); } }}/////////////// Draw or hide the cursor at the current X/Y location in a style// determined by the top two bits of the mode word..//void tty::TtyCursor (UINT16 state){ char st2[2]; INT16 dy = ycurr + GfxTextHeight(); UINT16 nFhue = ((state == ON) ? nFgnd : nBgnd); UINT16 nBhue = ((state == ON) ? nBgnd : nFgnd); switch (nMode & TTY_CsrMask) { case TTY_IBar: GfxTextColor(nFhue); GfxMoveTo(xcurr-2, ycurr), GfxLineTo(xcurr-1, ycurr); GfxMoveTo(xcurr+2, ycurr), GfxLineTo(xcurr+1, ycurr); GfxMoveTo(xcurr-2, dy), GfxLineTo(xcurr-1, dy); GfxMoveTo(xcurr+2, dy), GfxLineTo(xcurr+1, dy); GfxMoveTo(xcurr, ycurr+1), GfxLineTo(xcurr, dy-1); break; case TTY_InvBlk: st2[0] = pVmem[idx], st2[1] = '\0'; GfxTextColor(nFhue); GfxTextColorBg(nBhue); GfxText(xcurr, ycurr, st2, GFX_Replace); //GfxRect(xcurr, ycurr, xcurr+GfxTextExtent(st2), dy, GFX_Fill, hue); GfxTextColorBg(nFhue); GfxTextColor(nBhue); break; case TTY_Uscore: GfxTextColor(nFhue); st2[0] = pVmem[idx], st2[1] = '\0'; GfxMoveTo(xcurr, dy - GFX_UlnOffset); GfxLineTo(xcurr+GfxTextExtent(st2), dy-GFX_UlnOffset); GfxTextColor(nBhue); break; case TTY_CursorOff: break; }}/********************************** eof **********************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -