/*** SetMarkFile - Change markfile * * Purpose: * * Changes to a new markfile. * * Input: * val - String after the 'markfile' switch * * Output: * * Returns Error string if error, NULL otherwise * * Notes: * * We: * * UNDONE:o Magically ensure that the current markfile is up to date and * saved to disk. This means, at the very least, that there * can be no dirty files. * * o Remove the current markfile from the file list. * * o Read in the new markfile. * * o Invalidate all current marks. This is just marking them * invalid in the PFILE. * * *************************************************************************/ char * SetMarkFile ( char *val ) { REGISTER PFILE pFile; buffer tmpval; pathbuf pathname; strcpy ((char *) tmpval, val); if (NULL == CanonFilename (tmpval, pathname)) { sprintf (buf, "'%s': name is malformed", tmpval); return buf; } if (!(pFile = FileNameToHandle (pathname, NULL))) { pFile = AddFile (pathname); } if (!TESTFLAG(FLAGS(pFile), REAL) && !FileRead (pathname, pFile, FALSE)) { RemoveFile (pFile); sprintf (buf, "'%s' - %s", pathname, error()); return buf; } pFileMark = pFile; for (pFile = pFileHead; pFile; pFile = pFile->pFileNext) { if (!TESTFLAG(FLAGS(pFile), FAKE)) { RSETFLAG (FLAGS(pFile), VALMARKS); } } return NULL; }
/*** AddFMToFile - Add a bunch of marks to a file * * Purpose: * * Insert the marks from one FILEMARKS structure into another. The * target structure is in pfmCache. * * Input: * pFile - Target file * pfm - Source marks * cZero - # of columns to adjust source marks to fit into target file * zZero - # of lines to adjust source marks to fit into target file * * Output: None * *************************************************************************/ void AddFMToFile ( PFILE pFile, FILEMARKS * pfm, COL cZero, LINE lZero ) { REGISTER MARK UNALIGNED * pm; if (lZero || cZero) { for (pm = pfm->marks; !TESTFLAG(pm->flags, MF_DUMMY); (char *)pm += pm->cb) { pm->fl.lin += lZero; pm->fl.col += cZero; } } if (!fCacheMarks (pFile)) { (void)fFMtoPfile (pFile, pfm); return; } for (pm = pfm->marks; !TESTFLAG(pm->flags, MF_DUMMY); (char *)pm += pm->cb) { UpdMark (&pfmCache, pm->szName, pm->fl.lin+1, pm->fl.col+1, (flagType)pm->flags); } }
/*** WriteMarks - Write Marks back out to the markfile. * * Purpose: * * To update the markfile if any marks have changed * * Input: * pFile - owner of the marks * * Output: None. * *************************************************************************/ void WriteMarks ( PFILE pFile ) { REGISTER MARK UNALIGNED * pm; char szMark[BUFLEN]; char szFile[BUFLEN]; linebuf lbuf; LINE yMark, l; COL xMark; if (pFileMark == NULL || TESTFLAG(FLAGS(pFile), FAKE)) { return; } if (!fCacheMarks (pFile)) { return; } // First, we read the whole file looking for marks for // this file. When we find one, we look it up in the // cache to find the new value and write it back // out. Unchanged marks are not re-written. // for (l = 0L; l < pFileMark->cLines; l++) { GetLine (l, lbuf, pFileMark); if (sscanf (lbuf, " %[^ ] %[^ ] %ld %d ", szMark, szFile, &yMark, &xMark) >= 3) { if (!_stricmp (szFile, pFile->pName)) { if (pm = FindLocalMark (szMark, TRUE)) { sprintf (lbuf, "%s %s %ld %d", szMark, szFile, pm->fl.lin+1, pm->fl.col+1); PutLine (l, lbuf, pFileMark); RSETFLAG (pm->flags, MF_DIRTY); } } } } // Now we read through the cache to find any new marks. These // will be appended to the markfile. // for ( pm = pfmCache->marks; !TESTFLAG(pm->flags, MF_DUMMY); (char *)pm += pm->cb) { if (TESTFLAG (pm->flags, MF_DIRTY)) { sprintf (lbuf, "%s %s %ld %d", pm->szName, pFile->pName, pm->fl.lin + 1, pm->fl.col + 1); AppFile (lbuf, pFileMark); } } }
void fDoDel ( char *name, struct findType *pBuf, void *dummy ) { char *p; // // if it is a file, attempt to delete it // if (!TESTFLAG(pBuf->fbuf.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) { // // if file is read-only, make it writable // if (TESTFLAG(pBuf->fbuf.dwFileAttributes, FILE_ATTRIBUTE_READONLY)) { if(!SetFileAttributes(name, pBuf->fbuf.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY)) { return; } } _unlink (name); } else if( strcmp( pBuf->fbuf.cFileName, "." ) && strcmp( pBuf->fbuf.cFileName, ".." ) ) { // // if directory is read-only, make it writable // if (TESTFLAG(pBuf->fbuf.dwFileAttributes, FILE_ATTRIBUTE_READONLY)) { if(!SetFileAttributes(name, pBuf->fbuf.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY)) { return; } } // // clear out subdir first // p = strend( name ); pathcat( name, "*.*" ); forfile(name, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY, fDoDel, NULL); //if (!forfile(name, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY, fDoDel, NULL)) { // return; //} *p = 0; _rmdir (name); } dummy; }
/* FileStatus - compare logical info about a file with file on disk * * Compare the last modified time with the last snapshot. If the filename * contains metachars, the file is not believed to have changed. Further, if * the file is a pseudo file, it cannot have changed. * * pFile file of interest (contains mod time) * pName name of file to examine (when writing to diff. name) * * returns FILECHANGED if timestamps differ * FILEDELETED if file on disk does not exist * FILESAME if timestamps are the same */ int FileStatus ( PFILE pFile, char *pName ){ long modtime; if (TESTFLAG(FLAGS(pFile),FAKE)) { return FILESAME; } if (pName == NULL) { pName = pFile->pName; } if (*strbscan (pName, "?*") != 0) { return FILESAME; } if ((modtime = ModTime (pName)) == 0L) { return FILEDELETED; } if (pFile->modify != modtime) { return FILECHANGED; } return FILESAME; }
/* mPopToTop - clear off intermediate macros up to a fence */ void mPopToTop ( void ) { while (cMacUse && !TESTFLAG (mi[cMacUse-1].flags, EXEC)) { cMacUse--; } }
/* GetFileTypeName - return the text corresponding to the file type * * GetFileTypeName takes the file type as set in the file structure of the * current file and returns the textual string corresponding to that type. * * returns character pointer to the type-specific text */ char * GetFileTypeName ( void ) { if (TESTFLAG (FLAGS (pFileHead),FAKE)) { return "pseudo"; } return mpTypepName[FTYPE (pFileHead)]; }
void DoDisplay ( void ) { int Row, Col; if (pFileHead == NULL) { return; } if (TESTFLAG (fDisplay, RCURSOR)) { Row = YCUR(pInsCur) - YWIN(pInsCur) + WINYPOS(pWinCur); Col = XCUR(pInsCur) - XWIN(pInsCur) + WINXPOS(pWinCur); if ( Row >= YSIZE || Col >= XSIZE ) { docursor( XCUR(pInsCur), YCUR(pInsCur) ); } } /* * If text needs updating, do so. Return immediately if a keystroke was * pressed. */ if (TESTFLAG (fDisplay, RTEXT) && !DoText (0, YSIZE)) { return; } if ((fDisplayCursorLoc && TESTFLAG (fDisplay, RCURSOR)) || TESTFLAG (fDisplay, RSTATUS)) { DoStatus (); } if (TESTFLAG (fDisplay, RCURSOR)) { Row = YCUR(pInsCur) - YWIN(pInsCur) + WINYPOS(pWinCur); Col = XCUR(pInsCur) - XWIN(pInsCur) + WINXPOS(pWinCur); consoleMoveTo( Row, Col ); RSETFLAG (fDisplay, RCURSOR); } }
/*** makedirty * * * Input: * * Output: * *************************************************************************/ void makedirty ( REGISTER PFILE pFileDirty ) { if (!TESTFLAG(FLAGS(pFileDirty),DIRTY)) { if (pFileDirty == pFileHead) { SETFLAG (fDisplay, RSTATUS); } SETFLAG (FLAGS(pFileDirty), DIRTY); } }
/*** FindLocalMark - Find a mark in a FILEMARKS structure * * Purpose: * * To find a mark in the cached marks. If found, a pointer into * the cache is returned, * * Input: * pszMark - Mark Name * fDirtyOnly - TRUE => Return only changed marks. * * Output: * * Returns pointer to mark. * *************************************************************************/ MARK * FindLocalMark ( char * pszMark, flagType fDirtyOnly ) { REGISTER MARK UNALIGNED * pm; for (pm = pfmCache->marks; !TESTFLAG(pm->flags, MF_DUMMY) ; (char *)pm += pm->cb) { if (!_stricmp (pszMark, pm->szName)) { if (fDirtyOnly && !TESTFLAG(pm->flags, MF_DIRTY)) { return NULL; } else { return (MARK *)pm; } } assert (pm->cb); } return NULL; }
/* * NextUnread - return the inote of the next unread message * * arguments: * inote - start looking after this, -1 means start at beginning * * return value: * ERROR (-1) all messages read * any + num message number of next unread message */ IDOC PASCAL INTERNAL NextUnread ( INOTE inote ) { INT i; for ( i = ++inote; i <= inoteLast; i++) { GenerateFlags ( mpInoteIdoc [ i ] ); if ( TESTFLAG ( rgDoc [ mpInoteIdoc [ i ] ].flag, F_UNREAD ) ) break; } return ( i > inoteLast ) ? ERROR : mpInoteIdoc [ i ]; }
/*** fReadMarks - Read marks from the current markfile * * Purpose: * * Gets the current marks for a given file. * * Input: * pFile - File to read marks for. * * Output: * * Returns TRUE if pFile has marks and they are in VM, FALSE otherwise. * *************************************************************************/ flagType fReadMarks ( PFILE pFile ) { FILEMARKS UNALIGNED * pfm = NULL; LINE l; char szMark[BUFLEN]; char szFile[BUFLEN]; linebuf lbuf; LINE yMark; COL xMark; if (TESTFLAG (FLAGS(pFile), VALMARKS)) { return (flagType)(pFile->vaMarks != NULL); } // psuedo files cannot have marks // saved in the markfile. // if (pFileMark == NULL || TESTFLAG(FLAGS(pFile), FAKE)) { return FALSE; } for (l = 0L; l < pFileMark->cLines; l++) { GetLine (l, lbuf, pFileMark); if (sscanf (lbuf, " %[^ ] %[^ ] %ld %d ", szMark, szFile, &yMark, &xMark) >= 3) { if (!_stricmp (szFile, pFile->pName)) { UpdMark ((FILEMARKS **) &pfm, szMark, yMark, xMark, FALSE); } } } // Now pfm points to a good FILEMARKS structure. // First, throw away current marks. Then, if we // actually found some marks for this file, we // put them in VM. // return fFMtoPfile (pFile, (FILEMARKS *)pfm); }
/* SetCursor - place the visible cursor in some window * * hWnd window for cursor * x, y location of cursor in window */ VOID PASCAL INTERNAL SetCursor (HW hWnd, INT x, INT y) { if (!TESTFLAG (hWnd->fsFlag, WF_BLINK)) /* move cursor off screen */ #ifdef NT cursorInvisible (); #else cursor ( xSize + 1, ySize + 1 ); #endif else if (INRANGE (0, x, TWINWIDTH (hWnd)) && INRANGE (0, y, TWINHEIGHT (hWnd))) {
/* Look4Message - look for a message * * arguments: * inote starting with inote * i +1 or -1 * fLook4Undel search * * * * return value: * ERROR (-1) at the end of the header list * any + num message number of next message */ INOTE PASCAL INTERNAL Look4Inote ( INOTE inote, INT i, FLAG fLook4Undel ) { if ( inote != -1 ) { while ( ( inote = inote + i ) >= 0 && inote <= inoteLast ) { GenerateFlags ( inote ); if ( !fLook4Undel || !TESTFLAG (rgDoc[mpInoteIdoc[inote]].flag, F_DELETED ) ) return ( inote ); } } return ERROR; }
/*** GetMarkFromLoc - Return the first mark past a given location * * Purpose: * * To get a pointer to a mark given its file location. * * Input: * x, y - Mark location * * Output: * * Returns Pointer to the mark. * *************************************************************************/ MARK * GetMarkFromLoc ( LINE y, COL x ) { REGISTER MARK UNALIGNED * pm; for (pm = pfmCache->marks; !TESTFLAG(pm->flags, MF_DUMMY) ; (char *)pm += pm->cb) { if (pm->fl.lin > y || ((pm->fl.lin == y) && (pm->fl.col >= x))) { break; } } return (MARK *) pm; }
/*** AdjustMarks - Change later marks when one has changed * * Purpose: * * To update marks in a FILEMARKS structure after some lines have been * added or removed. * * Input: * pm - pointer to first mark that has changed. * yDelta - Number of lines to change by. May be negative * * Output: None * *************************************************************************/ void AdjustMarks ( REGISTER MARK * pm, LINE yDelta ) { REGISTER MARK UNALIGNED * pm1; assert (pm); pm1 = pm; for (;!TESTFLAG(pm1->flags, MF_DUMMY); (char *)pm1 += pm1->cb) { pm1->fl.lin += yDelta; SETFLAG (pm1->flags, MF_DIRTY); } fCacheDirty = TRUE; }
/*** DeleteMark - Remove a mark * * Purpose: * * Un-define a mark. * * Input: * pszMark - Mark to remove * * Output: None * * Notes: * * A message is displayed reporting on success or failure. * *************************************************************************/ void DeleteMark ( char * pszMark ) { REGISTER PFILE pFile; MARK UNALIGNED * pm; for (pFile = pFileHead; pFile; pFile = pFile->pFileNext) { if (TESTFLAG (FLAGS(pFile), VALMARKS) && fCacheMarks (pFile)) { if (pm = FindLocalMark (pszMark, FALSE)) { DelPMark ((MARK *)pm); domessage ("%s: mark deleted", pszMark); return; } } } printerror ("%s: Mark not found", pszMark); }
/* fFindLabel finds a label in macro text * * The goto macro functions call fFindLabel to find the appropriate label. * We scan the text (skipping quoted text) to find the :> leader for the label. * * pMI pointer to active macro instance * lbl label to find (case is not significant) with goto operator * =>, -> or +> This will be modified. * * returns TRUE iff label was found */ flagType fFindLabel ( struct macroInstanceType *pMI, buffer lbl ) { buffer lbuf; lbl[0] = ':'; pMI->text = pMI->beg; while (*pMI->text != '\0') { if (!TESTFLAG (fParseMacro (pMI, lbuf), GRAPH)) { if (!_stricmp (lbl, lbuf)) { return TRUE; } } } return FALSE; }
/*** GetFMFromFile - Generate a FILEMARKS for marks in a file region * * Purpose: * * Generates a subset of a FILEMARKS structure whose marks fall * within a certain range. Needed by MarkCopy*. * * Input: * pFile - File to get marks from * xLeft, yTop - Start of range * xRight, yBottom - End of range * * Output: * * Returns Pointer to new structure, NULL if there are no marks in range * *************************************************************************/ FILEMARKS * GetFMFromFile ( PFILE pFile, COL xLeft, LINE yTop, COL xRight, LINE yBottom ) { FILEMARKS UNALIGNED * pfm = NULL; REGISTER MARK UNALIGNED * pm; fl flStart; fl flEnd; flagType fInRange = FALSE; if (!fCacheMarks (pFile)) { return NULL; } flStart.lin = yTop; flStart.col = xLeft; flEnd.lin = yBottom; flEnd.col = xRight; for (pm = pfmCache->marks; !TESTFLAG(pm->flags, MF_DUMMY); (char *)pm += pm->cb) { if ((fInRange || flcmp (&flStart, (fl *) &pm->fl) < 1) && (flcmp ((fl *) &pm->fl, &flEnd) < 1)) { fInRange = TRUE; if ((pm->fl.col >= xLeft && pm->fl.col <= xRight)) { UpdMark ( (FILEMARKS **) &pfm, pm->szName, pm->fl.lin - yTop + 1, pm->fl.col - xLeft + 1, (flagType)pm->flags); } } else { break; /* We're out of range again*/ } } return (FILEMARKS *) pfm; }
/*** GoToMark - Move cursor to a mark * * Purpose: * * Goes to the named mark. * * Input: * pszMark - Name of mark to go to. * * Output: * * Returns TRUE if mark exists, FALSE, otherwise. * *************************************************************************/ flagType GoToMark ( char * pszMark ) { PFILE pFile; fl fl; if (pFile = FindMark (pszMark, &fl, TRUE)) { if (TESTFLAG(FLAGS(pFile), REAL) || FileRead (pFile->pName, pFile, FALSE)) { pFileToTop (pFile); cursorfl (fl); return TRUE; } else { return FALSE; } } else { printerror ("'%s': Mark not found", pszMark); return FALSE; } }
/*** fMacResponse - peek ahead and eat any embedded macro response * * Purpose: * Scans ahead in the macro text for an item beginning with a "<", which * supplies a response to the question asked by a preceding function. * * Input: * None * * Output: * Returns NULL if not found, -1 if the user is to be prompted, and a character * if a character is supplied. * * Exceptions: * none * *************************************************************************/ int fMacResponse ( void ) { int c; struct macroInstanceType *pMI; if (mtest()) { pMI = &mi[cMacUse-1]; if ((TESTFLAG (pMI->flags, INIT | GRAPH)) == 0) { if (*(pMI->text) != '<') return 0; c = (int)*(pMI->text+1); if ((c == 0) || (c == ' ')) { return -1; } pMI->text = whiteskip(pMI->text+2); return c; } } return -1; }
/*** UpdMark - Add a mark to a FILEMARKS * * Purpose: * * This creates the FILEMARKS structure, adds marks to it and * updates existing marks in it. The caller does not need to * know which of these is going to happen. * * Input: * ppfm - Pointer to a pointer to FILEMARKS. * pszMark - Mark name. * yMark - Mark location (1-based) * xMark * fTemp - TRUE => This marks should not be written to the markfile * * Output: None. *ppfm may be changed * * Notes: * * The first argument is a ** because the * will be updated when a * re-LMAlloc is required. * *************************************************************************/ void UpdMark ( FILEMARKS ** ppfm, char * pszMark, LINE yMark, COL xMark, flagType flags ) { FILEMARKS UNALIGNED * pfm; FILEMARKS UNALIGNED * pfmOld; /* pfm prior to realloc */ REGISTER MARK UNALIGNED * pm; int cbNewMark; fl flMark; flagType fExist = FALSE; assert (ppfm); /* Convert to 0-based */ flMark.lin = yMark-1; flMark.col = xMark-1; cbNewMark = sizeof(MARK) + strlen(pszMark); // If we already have a FILEMARKS structure, // we look for the slot in pfm->marks // where the new mark will go. // if (pfm = *ppfm) { for (pm = pfm->marks; !TESTFLAG(pm->flags, MF_DUMMY); (char *)pm += pm->cb) { if (!_stricmp (pszMark, pm->szName)) { fExist = TRUE; break; } // Check for current mark coming later than // new mark // if (flcmp ((fl *) &pm->fl, &flMark) > 0) { break; } } } else { // New structure. Allocate mem and create // a dummy mark. // pfm = (FILEMARKS *)ZEROMALLOC (sizeof(FILEMARKS)); pfm->cb = sizeof(FILEMARKS); pm = pfm->marks; pm->cb = sizeof(MARK); pm->fl.lin = 0x7FFFFFFF; pm->fl.col = 0x7FFF; pm->szName[0] = '\0'; pm->flags = MF_DUMMY; } // At this point, pfm points to the current FILEMARKS // structure, and pm points into that structure at // the place where the new mark will go, or the existing // mark be updated. // if (!fExist) { pfmOld = pfm; // First, get enough extra space for a new mark, adjusting pm // if a new alloc was required // pfm = (FILEMARKS *)ZEROREALLOC((PVOID)pfm, pfm->cb + cbNewMark); if (pfmOld != pfm) { pm = (MARK *)((char *)pfm + ((char *)pm - (char *)pfmOld)); } // Now pm points to the location in pfm where // our new mark should go. We will move the // original filemarks up to leave space for the // new one. // memmove ((char *)((char *)pm + cbNewMark), (char *)pm, pfm->cb - ((char *)pm - (char *)pfm)); strcpy (pm->szName, pszMark); pm->flags = 0; pm->cb = cbNewMark; pfm->cb += cbNewMark; } if (pfm == pfmCache) { fCacheDirty = TRUE; } pm->flags = flags; pm->fl = flMark; *ppfm = (FILEMARKS *)pfm; }
/// // CTimedText::Update() // void CTimedText::Update() { // bail if we are not set up (current state == none), // or if we are finished // or if we are not running if ( ( m_state == CTIMEDTEXT_NONE ) || ( m_state == CTIMEDTEXT_FINISHED ) || !TESTFLAG( m_flags, CTIMEDTEXTFLAG_RUNNING ) ) { return; } // update the elapsed time float currentUpdateTime; currentUpdateTime = g_pLTClient->GetTime(); m_timeElapsed += currentUpdateTime - m_prevUpdateTime; m_prevUpdateTime = currentUpdateTime; // check if we're just waiting to start if ( m_state == CTIMEDTEXT_INITIAL_DELAY ) { if ( m_timeElapsed < m_initialDelay ) { // still waiting, don't do anything return; } // no longer waiting, change to next state m_state = CTIMEDTEXT_TIMING; m_timeElapsed = m_timeElapsed - m_initialDelay; } // determine how much text we've done so far float processedTime; if ( m_state == CTIMEDTEXT_TIMING ) { // the processed time is important for timing text // because it determines what position we have reached // in the text (how much text is revealed) processedTime = ( m_charactersProcessed - m_nNewlinesProcessed ) * m_characterDelay; // Get the minimum of number of lines before scrolling // or the number of lines we've processed. This will be // the number of line delays to use. float numberOfNonScrolls; if ( m_linesProcessed > ( m_numberOfLinesBeforeScroll - 1 ) ) { numberOfNonScrolls = (float)( m_numberOfLinesBeforeScroll - 1 ); } else { numberOfNonScrolls = m_linesProcessed; } // add the proper number of line delays to the processed time processedTime += numberOfNonScrolls * m_lineDelay; // determine how many times we've scrolled so far float numberOfScrolls; numberOfScrolls = m_linesProcessed - (float)( m_numberOfLinesBeforeScroll - 1 ); if ( numberOfScrolls > 0 ) { processedTime += numberOfScrolls * m_scrollTime; } } else { // the other states are easier cause they are // just straight timers and we don't have to know // where we are in the text processedTime = m_timeElapsed; } // determine where we currently are in the text int textPos; textPos = m_charactersProcessed; ASSERT( textPos <= m_textLen ); // // bring our text up to date // // while processed time is less than true elapsed time while (processedTime <= m_timeElapsed ) { // *check state if ( m_state == CTIMEDTEXT_TIMING ) { if ( TESTFLAG( m_flags, CTIMEDTEXTFLAG_SCROLLING ) ) { // // the text is currently scrolling // float timeLeft; timeLeft = m_timeElapsed - m_scrollRefTime; uint8 textHeight; textHeight = m_text->GetCharScreenHeight(); if ( timeLeft < m_scrollTime ) { // move text to proper position m_posY = m_scrollRefPosY - ( textHeight * timeLeft / m_scrollTime ); #ifdef TIMED_TEXT_FADE_TOP_LINE // fade top line by appropiate amount for ( int ii = m_nLineFadeCharStart; ii < m_nLineFadeCharEnd; ++ii ) { g_pLTClient->GetDrawPrim()->SetALPHA( &m_text->GetPolys()[ ii ], ( uint8 ) ( ALPHA_OPAQUE - ALPHA_OPAQUE * timeLeft / m_scrollTime ) ); } #endif // TIMED_TEXT_FADE_TOP_LINE break; } else { // move text to the final position m_posY = m_scrollRefPosY - textHeight; // increment the current time processedTime = m_scrollRefTime + m_scrollTime; // update our line count ++m_linesProcessed; #ifdef TIMED_TEXT_FADE_TOP_LINE // fade line completely for ( int ii = m_nLineFadeCharStart; ii < m_nLineFadeCharEnd; ++ii ) { g_pLTClient->GetDrawPrim()->SetALPHA( &m_text->GetPolys()[ ii ], 0 ); } // the next line to fade starts where this one ended m_nLineFadeCharStart = m_nLineFadeCharEnd; #endif // TIMED_TEXT_FADE_TOP_LINE // reset our references m_scrollRefPosY = 0; m_scrollRefTime = 0; // remember the new line height m_fLineYPos = m_text->GetPolys()[ textPos ].verts[ 0 ].y; // done scrolling CLEARFLAG( m_flags, CTIMEDTEXTFLAG_SCROLLING ); } } // if we are done displaying the text else if ( textPos >= m_textLen ) { // reset time elapsed m_timeElapsed -= processedTime; processedTime = 0; if ( m_hTextDisplaySound != LTNULL ) { // kill the looping typing sound g_pLTClient->SoundMgr()->KillSound( m_hTextDisplaySound ); m_hTextDisplaySound = LTNULL; } // switch current state to complete m_state = CTIMEDTEXT_COMPLETE; ASSERT( m_timeElapsed >= 0 ); } // else if the text at the current position is a linefeed else if ( ( m_text->GetPolys()[ textPos ].verts[ 0 ].y - m_fLineYPos ) > 0.5f ) { // The only way we know we have a new line is if the polygon // has a different y value than the one before it. if ( m_linesProcessed >= ( m_numberOfLinesBeforeScroll - 1 ) ) { if ( !TESTFLAG( m_flags, CTIMEDTEXTFLAG_SCROLLING ) ) { // set up to scroll SETFLAG( m_flags, CTIMEDTEXTFLAG_SCROLLING ); m_scrollRefTime = processedTime; m_scrollRefPosY = m_posY; #ifdef TIMED_TEXT_FADE_TOP_LINE // to fade the top line of text, start from where // the line starts and scan for end of line for ( m_nLineFadeCharEnd = m_nLineFadeCharStart + 1; ( ( m_text->GetPolys()[ m_nLineFadeCharEnd ].verts[ 0 ].y - m_text->GetPolys()[ m_nLineFadeCharStart ].verts[ 0 ].y ) < 0.5f ); ++m_nLineFadeCharEnd ) { } #endif // TIMED_TEXT_FADE_TOP_LINE if ( m_hTextDisplaySound != LTNULL ) { // kill the looping typing sound g_pLTClient->SoundMgr()->KillSound( m_hTextDisplaySound ); m_hTextDisplaySound = LTNULL; } // play the scroll sound if ( m_scrollSoundName[ 0 ] != '\0' ) { g_pClientSoundMgr->PlayInterfaceSound( m_scrollSoundName ); } } } else { // increment the current time processedTime += m_lineDelay; // update our line count ++m_linesProcessed; m_fLineYPos = m_text->GetPolys()[ textPos ].verts[ 0 ].y; if ( m_hTextDisplaySound != LTNULL ) { // kill the looping typing sound g_pLTClient->SoundMgr()->KillSound( m_hTextDisplaySound ); m_hTextDisplaySound = LTNULL; } } } else if ( m_text->GetText()[ textPos ] == '\n' ) { // Ignore newlines completely. We want to keep track of them so // we know where we are in the text, but we won't do any // of the timing delay calculations with them. ++m_charactersProcessed; ++m_nNewlinesProcessed; ++textPos; } // else if the text at the current position is printable else { // play the sound if ( ( m_hTextDisplaySound == LTNULL ) && ( m_textDisplaySoundName[ 0 ] != '\0' ) ) { m_hTextDisplaySound = g_pClientSoundMgr->PlayInterfaceSound( m_textDisplaySoundName, ( PLAYSOUND_LOOP | PLAYSOUND_GETHANDLE | PLAYSOUND_CLIENT ) ); } // update our character count ++m_charactersProcessed; ++textPos; // increment the current time processedTime += m_characterDelay; } } // else if complete else if ( m_state == CTIMEDTEXT_COMPLETE ) { // *check to switch to next state // if current time greater than delay if ( processedTime >= m_completeDelay ) { // reset time elapsed m_timeElapsed -= processedTime; processedTime = 0; // switch current state to fade m_state = CTIMEDTEXT_FADING; } else { break; } } // else if fading else if ( m_state == CTIMEDTEXT_FADING ) { // *check to switch to next state // if current time is greater than fade time if ( processedTime >= m_fadeTime ) { // switch current state to finished m_state = CTIMEDTEXT_FINISHED; } else { //TEMP: turn the text to black break; } } // else if finished else { CLEARFLAG( m_flags, ( CTIMEDTEXTFLAG_RUNNING | CTIMEDTEXTFLAG_DISPLAY ) ); // DONE break; } } #ifdef TIMEDTEXT_DEBUG // put this here to make debugging easier // if a lot of time is spent in the debugger // in the update loop, we won't count that // time against the timed text m_prevUpdateTime = g_pLTClient->GetTime(); #endif // TIMEDTEXT_DEBUG }
/*** MarkDelBox - Adjust Marks after a DelBox * * Purpose: * * After deleting a box of text, we must remove any marks that are * defined inside it, then shift left any marks that are to the * right of it. * * Input: * pFile - Affected file * xLeft, yTop - Upper left hand corner of box * xRight, yBottom - Lower right hand corner of box * * Output: None * *************************************************************************/ void MarkDelBox ( PFILE pFile, COL xLeft, LINE yTop, COL xRight, LINE yBottom ) { MARK UNALIGNED * pm; MARK UNALIGNED * pmStart = NULL; MARK UNALIGNED * pmEnd = NULL; fl flUpLeft; fl flLoRight; flagType fAgain; flagType fInBox = FALSE; /* Marks are within box top/bottom */ if (!fCacheMarks (pFile)) { return; } /* yBottom++; WHY? */ flUpLeft.lin = yTop; flUpLeft.col = xLeft; flLoRight.lin = yBottom; flLoRight.col = xRight; for (pm = pfmCache->marks; !TESTFLAG(pm->flags, MF_DUMMY) ; !fAgain && ((char *)pm += pm->cb)) { /* First, look for lowest possible mark */ fAgain = FALSE; if (!fInBox) { if (flcmp (&flUpLeft, (fl *) &pm->fl) < 1) { fAgain = TRUE; fInBox = TRUE; } else { ; } } else if (flcmp ((fl *) &pm->fl, &flLoRight) < 1) { /* Now we're in range. Check ** for being inside the box. */ if (pm->fl.col >= xLeft) { if (pm->fl.col <= xRight) { DelPMark ((MARK *) pm); fAgain = TRUE; } else { /* Mark to the right of box */ pm->fl.col -= xRight - xLeft + 1; } } else { ; } } else { if (pm->fl.lin == yBottom) { pm->fl.col -= xRight - xLeft + 1; } else { break; /* We've gone past the box */ } } } }
/*** MarkDelStream - Adjust Marks after a DelStream * * Purpose: * * After DelStream or DelLines removes a stream (DelLine removes a * "stream" with the beginning and ending points at the left and right * edges of the file), this takes care of updating any remaining * marks. * * Input: * pFile - Affected file * xStart - 0-based starting point * yStart * xEnd - 0-based ending point * yEnd * * Output: None * *************************************************************************/ void MarkDelStream ( PFILE pFile, COL xStart, LINE yStart, COL xEnd, LINE yEnd ) { REGISTER MARK UNALIGNED * pm; MARK UNALIGNED * pmStart = NULL; MARK UNALIGNED * pmEnd = NULL; fl flStart; fl flEnd; flagType fAgain = FALSE; if (!fCacheMarks (pFile)) { return; } /* yEnd++; WHY? */ flStart.lin = yStart; flStart.col = xStart; flEnd.lin = yEnd; flEnd.col = xEnd; for (pm = pfmCache->marks; pmEnd == NULL ; (char *)pm += pm->cb) { // Look for first mark past beginning // of stream. Assume for the moment that // it is inside the stream // if (pmStart == NULL) { if (flcmp (&flStart, (fl *) &pm->fl) < 1) { pmStart = pm; } else { continue; } } // A first mark has been found. We start // looking for the first mark past the end // of the stream. If these are the same, // there are no marks to remove. // if (flcmp (&flEnd, (fl *) &pm->fl) < 1) { // We know that we will end up here // because the last "mark" is higher // than any real mark // if ((pmEnd = pm) != pmStart) // We're here if there were // any marks inside the deleted // stream // memmove ((char *)pmStart, (char *)pmEnd, ((char *)pfmCache + pfmCache->cb) - (char *)pmEnd ); if (pmStart->fl.lin == yEnd) { pmStart->fl.col -= xEnd; } AdjustMarks ((MARK *)pmStart, yStart - (yEnd + 1)); } assert (pm->cb || (TESTFLAG(pm->flags, MF_DUMMY) && pm->fl.lin == 0x7FFFFFFF && pm->fl.col == 0x7FFF)); } }
/// // CTimedText::Render() // void CTimedText::Render() { // bail if we are not set up (current state == none), // or if we are finished // or if we are not running if ( ( m_state == CTIMEDTEXT_NONE ) || ( m_state == CTIMEDTEXT_INITIAL_DELAY ) || ( m_state == CTIMEDTEXT_FINISHED ) || !TESTFLAG( m_flags, CTIMEDTEXTFLAG_DISPLAY ) ) { return; } // if we are fading, setup the alpha uint8 alpha; alpha = ( uint8 ) ALPHA_OPAQUE; int startChar; int endChar; startChar = 0; endChar = 0; if ( m_state == CTIMEDTEXT_TIMING ) { endChar = m_charactersProcessed; } else if ( m_state == CTIMEDTEXT_COMPLETE ) { // just display everything like normal startChar = 0; endChar = m_textLen; } else if ( m_state == CTIMEDTEXT_FADING ) { // just display everything like normal startChar = 0; endChar = m_textLen; alpha = ( uint8 ) (ALPHA_OPAQUE - ALPHA_OPAQUE * ( m_timeElapsed / m_fadeTime )); } else { // we are in the wrong state and shouldn't be here ASSERT( 0 ); } // drop shadow if necessary if ( TESTFLAG( m_flags, CTIMEDTEXTFLAG_USE_DROPPED_SHADOW ) ) { // change the text appearance to a drop shadow m_text->SetColor( ( alpha << 24 ) | SETRGB( 0.0f, 0.0f, 0.0f ) ); m_text->SetPosition( ( m_posX + 2 ), ( m_posY + 2 ) ); // show the amount of text we should reveal so far if ( TESTFLAG( m_flags, CTIMEDTEXTFLAG_USE_CLIP_RECT ) ) { m_text->RenderClipped( &m_clipRect, startChar, endChar ); } else { m_text->Render( startChar, endChar ); } // set the text back m_text->SetColor( ( alpha << 24 ) | m_color ); m_text->SetPosition( m_posX, m_posY ); } // show the amount of text we should reveal so far m_text->SetColor( ( alpha << 24 ) | m_color ); if ( TESTFLAG( m_flags, CTIMEDTEXTFLAG_USE_CLIP_RECT ) ) { m_text->RenderClipped( &m_clipRect, startChar, endChar ); } else { m_text->Render( startChar, endChar ); } }
flagType DoText ( int yLow, int yHigh ) { REGISTER int yCur; int yMin = -1; int yMax = 0; flagType fReturn = TRUE; struct lineAttr *plaFile = NULL; struct lineAttr *plaScr = NULL; struct lineAttr *plaFileLine; struct lineAttr *plaScrLine; char *pchFileLine = NULL; char pchScrLine[ 2 * sizeof(linebuf) * (1 + sizeof(struct lineAttr))]; int cchScrLine; // int chkpnt = yHigh - yLow > 25 ? 20 : 5; int chkpnt = yHigh - yLow > 25 ? 10 : 3; fReDraw = FALSE; plaScr = (struct lineAttr *) (pchScrLine + sizeof(linebuf)); if (cWin > 1) { pchFileLine = pchScrLine + sizeof(linebuf) * (1 + sizeof(struct lineAttr)); plaFile = (struct lineAttr *) (pchFileLine + sizeof(linebuf)); } /* * For each line in the window, if the line is marked changed, update it. */ for (yCur = yLow; yCur < yHigh; ) { if (TESTFLAG(fChange[yCur], FMODIFY)) { if (yMin == -1) { yMin = yCur; } yMax = yCur; /* * get and display the line */ plaScrLine = plaScr; plaFileLine = plaFile; cchScrLine = DisplayLine (yCur, pchScrLine, &plaScrLine, pchFileLine, &plaFileLine); coutb (0, yCur, pchScrLine, cchScrLine, plaScrLine); RSETFLAG(fChange[yCur],FMODIFY); /* * if it is time to check, and there is a character waiting, stop * the update process, and go process it */ if ( (yCur % chkpnt == 0) && TypeAhead() ) { fReturn = FALSE; break; } } yCur++; } if (fReturn) { RSETFLAG (fDisplay, RTEXT); } // // Update the screen // fReDraw = TRUE; vout(0,0,NULL,0,0); return fReturn; }
void DoStatus ( void ) { struct lineAttr rglaStatus[10]; /* color array for status line */ int cch; int ilaStatus = 0; /* index into color array */ int i; char *pchEndBuf; /* save for end of buffer */ char buf[512]; /* * Start with filename, and file type */ strcpy (buf, pFileHead->pName); strcat (buf, " ("); strcpy ((char *)strend(buf), GetFileTypeName ()); /* * Add other file characterisctics */ if (!TESTFLAG (FLAGS (pFileHead), DOSFILE)) { strcat (buf," NL"); } if (TESTFLAG (FLAGS (pFileHead), TEMP)) { strcat (buf, " temp"); } if ((TESTFLAG (FLAGS (pFileHead), READONLY)) | fGlobalRO) { strcat (buf, " No-Edit"); } if (TESTFLAG (FLAGS (pFileHead), DISKRO)) { strcat (buf, " RO-File"); } rglaStatus[ilaStatus].attr = CINDEX(staColor); rglaStatus[ilaStatus++].len = (unsigned char) strlen (buf); if (TESTFLAG (FLAGS(pFileHead), DIRTY)) { strcat (buf, " modified"); rglaStatus[ilaStatus].attr = CINDEX(errColor); rglaStatus[ilaStatus++].len = 9; } pchEndBuf = strend (buf); sprintf (strend(buf), ") Length=%ld ", pFileHead->cLines); /* * Add current location */ if (fDisplayCursorLoc) { sprintf (strend(buf), "Cursor=(%ld,%d)", YCUR(pInsCur)+1, XCUR(pInsCur)+1); } else { sprintf (strend(buf), "Window=(%ld,%d)", YWIN(pInsCur)+1, XWIN(pInsCur)+1); } rglaStatus[ilaStatus].attr = CINDEX(staColor); rglaStatus[ilaStatus++].len = (unsigned char) (strend(buf) - pchEndBuf); /* * Add global state indicators */ if (fInsert | fMeta | fCtrlc | fMacroRecord) { rglaStatus[ilaStatus].attr = CINDEX(infColor); rglaStatus[ilaStatus].len = 0; if (fInsert) { strcat (buf, " insert"); rglaStatus[ilaStatus].len += 7; } if (fMeta) { strcat (buf, " meta"); rglaStatus[ilaStatus].len += 5; } if (fCtrlc) { strcat (buf, " cancel"); rglaStatus[ilaStatus].len += 7; fCtrlc = FALSE; FlushInput (); } if (fMacroRecord) { strcat (buf, " REC"); rglaStatus[ilaStatus].len += 4; } ilaStatus++; } rglaStatus[ilaStatus].attr = CINDEX(staColor); rglaStatus[ilaStatus].len = 0xffff; pchEndBuf = buf; /* * if the net result is too long, eat the first part of the filename with * an elipses (Leave room for BC as well). */ cch = strlen(buf) - (XSIZE - 4); if (cch > 0) { pchEndBuf = buf + cch; pchEndBuf[0] = '.'; pchEndBuf[1] = '.'; pchEndBuf[2] = '.'; i = 0; while ( cch && i <= ilaStatus ) { if ( (int)rglaStatus[i].len > cch ) { rglaStatus[i].len -= cch; cch = 0; } else { cch -= rglaStatus[i].len; rglaStatus[i].len = 0; } i++; } } fReDraw = FALSE; coutb (0, YSIZE+1, pchEndBuf, strlen(pchEndBuf), rglaStatus); fReDraw = TRUE; voutb (XSIZE-2, YSIZE+1, BTWorking() ? "BP" : " ", 2, errColor); RSETFLAG (fDisplay, RSTATUS); }
/*** FindMark - Get a mark's file location - used from outside * * Purpose: * * Find a mark * * Input: * pszMark - Mark to search for. * fCheckAllFiles - TRUE => Search through all files for mark * FALSE => Look in only the current file * * Output: * * pfl - fl of mark. * * Returns pFile of file the mark is in, NULL if mark is not found. * *************************************************************************/ PFILE FindMark ( char * pszMark, fl * pfl, flagType fCheckAllFiles ) { REGISTER PFILE pFile; MARK UNALIGNED* pm; char szMark[BUFLEN]; char szFile[BUFLEN]; linebuf lbuf; LINE y, l; COL x; // If we are checking the current file only, // make sure it's cached and check it. // if (!fCheckAllFiles) { if (fCacheMarks (pFileHead) && (pm = FindLocalMark (pszMark, FALSE))) { *pfl = pm->fl; //return pFile; return pFileHead; } else { return NULL; } } // Now, trundle through the pFile list // looking at the marks we have already // read from the markfile. // for (pFile = pFileHead; pFile; pFile = pFile->pFileNext) { if (TESTFLAG (FLAGS(pFile), VALMARKS) && fCacheMarks (pFile)) { if (pm = FindLocalMark (pszMark, FALSE)) { *pfl = pm->fl; return pFile; } } } // None of the files we have read so far // has the mark defined. We'll make one // pass through the markfile to see if // it's there. // if (pFileMark) { for (l = 0L; l < pFileMark->cLines; l++) { GetLine (l, lbuf, pFileMark); if (sscanf (lbuf, " %[^ ] %[^ ] %ld %d ", szMark, buf, &y, &x) >= 3) if (!_stricmp (szMark, pszMark)) { CanonFilename (buf, szFile); if (!(pFile = FileNameToHandle (szFile, NULL))) { pFile = AddFile (szFile); } (void)fReadMarks (pFile); pfl->lin = y - 1; pfl->col = x - 1; return pFile; } } } return NULL; }
/* fChangeFile - change the current file, drive or directory. We form the * canonicalized name and attempt to find it in our internal list. If * present, then things are simple: relink it to the head of the current * window instance set. If not present, then we need to read it in. * * The actual algorithm is much simpler: * * If file not in file list then * create new entry in file list * Find file in file list * If file not in window instance list then * add file to top of window instance list * while files in window instance list do * select top file * if file is in memory then * change succeeded * else * if read in succeeds then * change succeeded * pop off top file * change failed * * * fShort TRUE => allow searching for short names * name name of file. * * Returns: TRUE if change succeeded * FALSE otherwise */ flagType fChangeFile ( flagType fShort, char *name ) { PFILE pFileTmp; pathbuf bufCanon; flagType fRead; char *p; // // If they explicitly specified .\ skip shortname checks // if (name[0] == '.' && name[1] == '\\') { fShort = FALSE; } // // Turn file name into canonical form // if (!CanonFilename (name, bufCanon)) { // // We may have failed because a drive or directory // went away. If the file named is on the file // list, we remove it. // printerror ("Cannot access %s - %s", name, error () ); pFileTmp = FileNameToHandle (name, (fShort && fShortNames) ? name : NULL); if (pFileTmp != NULL) { RemoveFile (pFileTmp); } return FALSE; } // // name has the input name // bufCanon has the full "real" name // // Check to see if the file is in the current file set // pFileTmp = FileNameToHandle (bufCanon, (fShort && fShortNames) ? name : NULL); if (pFileTmp == NULL) { // // File not loaded. If it is a directory, change to it // if (strlen (bufCanon) == 2 && bufCanon[1] == ':') { bufCanon[2] = '\\'; } if (_chdir (bufCanon) != -1) { domessage ("Changed directory to %s", bufCanon); return TRUE; } // // Must be a file. Create a new internal file for it // pFileTmp = AddFile (bufCanon); } // // Bring the found file to the top of the MRU list // pFileToTop (pFileTmp); // // if the file is not currently in memory, read it in // domessage (NULL); if (((FLAGS (pFileHead) & (REAL|REFRESH)) == REAL) || (fRead = FileRead (pFileHead->pName, pFileHead, TRUE))) { // If we just read in the file AND the file is new then // reset cached location to TOF. // if (fRead && TESTFLAG (FLAGS (pFileHead), NEW)) { YCUR(pInsCur) = 0; XCUR(pInsCur) = 0; } fSyncFile (pFileHead, TRUE); cursorfl (pInsCur->flCursorCur); fInitFileMac (pFileHead); // // Set the window's title // p = pFileHead->pName + strlen(pFileHead->pName); while ( p > pFileHead->pName && *p != '\\' ) { p--; } if ( *p == '\\' ) { p++; } sprintf( bufCanon, "%s - %s", pOrigTitle, p ); SetConsoleTitle( bufCanon ); return TRUE; } // The file was not successfully read in. Remove this instance and // return the indicated error. // RemoveTop (); return FALSE; }