/
Crimson2/alias/
Crimson2/area.tmp/
Crimson2/area.tmp/AnomalySpaceDock/
Crimson2/area.tmp/AnomalyStation/
Crimson2/area.tmp/AntHill/
Crimson2/area.tmp/ArcticTerrarium/
Crimson2/area.tmp/BuilderCity/
Crimson2/area.tmp/Dungeon/
Crimson2/area.tmp/MiningDock/
Crimson2/area.tmp/PipeSystem/
Crimson2/area.tmp/RattArea/
Crimson2/area.tmp/RobotFactory/
Crimson2/area.tmp/SilverDale/
Crimson2/area.tmp/StarshipFearless/
Crimson2/area.tmp/StationConduits/
Crimson2/area.tmp/TerrariumAlpha/
Crimson2/area.tmp/TerrariumBeta/
Crimson2/area.tmp/TestArea/
Crimson2/area.tmp/Void/
Crimson2/area/
Crimson2/area/AnomalySpaceDock/
Crimson2/area/AnomalyStation/
Crimson2/area/MiningDock/
Crimson2/area/PipeSystem/
Crimson2/area/SilverDale/
Crimson2/area/StationConduits/
Crimson2/area/Void/
Crimson2/board/
Crimson2/clone/
Crimson2/lib/
Crimson2/mole/
Crimson2/mole/mole_src/HELP/
Crimson2/player/
Crimson2/util/
Crimson2/wldedit/
Crimson2/wldedit/res/
// termbuf.h
// two-letter descriptor: tb
//
// This module provides a terminal buffer functionality

#ifndef _TERMBUF_H_
#define _TERMBUF_H_

/* general purpose macros */
#define TB_MAX(x,y) (x>y?x:y)
#define TB_MIN(x,y) (x<y?x:y)


/* character access definitions - see note below for more detail */
#define TB_CHARMASK       0x0FFL
#define TB_COLOURDEPTH    4     /* # colours = 1<<TB_COLOURDEPTH */
#define TB_FCOLOURMASK    (((1L<<TB_COLOURDEPTH)-1L)<<8)
#define TB_BCOLOURMASK    (((1L<<TB_COLOURDEPTH)-1L)<<(TB_COLOURDEPTH+8))
#define TB_EFFECTMASK     (0xFFFFFFFFL-TB_CHARMASK-TB_FCOLOURMASK-TB_BCOLOURMASK)
/* character access macros - see note below for more detail */
#define TB_MAKECHAR(x)    ((unsigned long)(x))
#define TB_MAKEFCOLOUR(x) (((unsigned long)(x))<<8)                    /* Foregnd colour */
#define TB_MAKEBCOLOUR(x) (((unsigned long)(x))<<(TB_COLOURDEPTH+8))   /* Backgnd colour */
#define TB_MAKEEFFECT(x)  (((unsigned long)(x))<<(TB_COLOURDEPTH*2+8)) /* effect bits (underline, bold, etc) */
#define TB_EXTCHAR(x)     (((unsigned long)(x)) & TB_CHARMASK)         /* EXTract CHARacter */
#define TB_EXTFCOLOUR(x)  ((((unsigned long)(x)) & TB_FCOLOURMASK)>>8)
#define TB_EXTBCOLOUR(x)  ((((unsigned long)(x)) & TB_BCOLOURMASK)>>(TB_COLOURDEPTH+8))
#define TB_EXTEFFECT(x)   ((((unsigned long)(x)) & TB_EFFECTMASK)>>(TB_COLOURDEPTH*2+8))

/* function Notify messages */
#define TBNOTIFY_SCROLL   0x0001  /* scroll occurred; P0=#lines scrolled */
#define TBNOTIFY_NEWCHAR  0x0002  /* new character; P0=startX, P1=startY, P2=endX, P3=endY - buffer coordinates */
#define TBNOTIFY_MOVECUR  0x0003  /* new cursor pos; P0=X, P1=Y */
#define TBNOTIFY_RESIZE   0x0004  /* screen has been resized: P0=newX, P1=newY */

#define TBTAB_NONE        0x00    /* no tab stop present         */
#define TBTAB_LEFTALIGN   0x01    /*             |hello there    */
#define TBTAB_RIGHTALIGN  0x02    /*  hello there|               */
#define TBTAB_CENTREALIGN 0x03    /*        hello|there          */

typedef struct TBTERMBUFtag {
	HGLOBAL tMemory;          /* memory handle for THIS STRUCTURE */
	HGLOBAL tBufferMemory;    /* memory handle for tBuffer */
	unsigned long *tBuffer;   /* our screen data (terminal buffer) */
	unsigned long *tTab;      /* tab stops - an "extra" line alloc'ed at the end of the tBuffer */
	long tTopY;        /* pointer to the "top" row - see discussion below */
	long tBufX,tBufY;  /* buffer dimentions */
	long tCurX,tCurY;  /* cursor position, relative to top left of tScr (active screen) */
	long tScrX,tScrY;  /* "active screen" dimentions */
  int  tScrollRegionActive; /* 0 if no scrolling region defined (ie: whole screen), otherwise non-zero */
	long tSRX1,tSRX2,tSRY1,tSRY2; /* scrolling region -- invalid unless tScrollRegionActive!=0 */
  long tCurrentAttribute; /* current colour/attribute word */
  long tHLStartX,tHLStartY; /* hilight start point */
  long tHLEndX,tHLEndY; /* hilight end point */
  COLORREF tColourBank[1<<TB_COLOURDEPTH];  /* colour cross reference */
  HPEN tColourPen[1<<TB_COLOURDEPTH];
	(*tNotifyFn)(unsigned long p_ID, unsigned int p_Operation, unsigned long p_P0, unsigned long p_P1, unsigned long p_P2, unsigned long p_P3); /* function called to notify of scrolling etc. */
  long tHTab; /* Horizontal Tab size */
  unsigned long tID;  /* for application's use - application-defined ID tag */
                      /* note this can be used in tNotifyFn to determine the ID of the terminal */
	long tSaveCurrentAttribute;
	long tSaveCurX,tSaveCurY;
  BOOL tAutoRightMargin;
} TBTERMBUF;

/* NOTE NOTE NOTE
 * Ok, let's review how this sucker works.
 *
 * First of all, there's the buffer. This is a wack of memory which includes
 * the current screen as well as the scrollback buffer. The visible or "active"
 * screen is merely a subset of the buffer. The active screen is the "VT100"
 * terminal; if you "clear the screen", you will set all the bytes in the
 * active screen to zero. This is to facilitate ansi codes which assume
 * a given screen size of X,Y (usually 80x25).
 *
 * The buffer starts at tBuffer and has tBufY rows of tBufX characters each.
 *
 * The location of the "active screen" is defined by tTopY. This is a Y offset
 * in "buffer coordinates" (ie: relative to tBuffer; tTopY=0 corresponds to the
 * row starting at tBuffer[0], tTopY=1 corresponds to the row starting at
 * tBuffer[tBufX), etc.) tTopY is the row number of the **TOP** of the screen.
 * At the same time, tScrX and tScrY are the X and Y size of the screen relative to
 * tTopY, assuming that tTopY points to the top left corner of the active screen.
 * confused yet? Ok, let's add this all up in a neat little diagram:
 *
 *   NOTE: "->" designates "points to"                      tBufX
 *                                                             |
 *               ______________________________________________V
 *     tBuffer->|                                              |
 *              |                                              |
 *              |      scrollback data                         |
 *              |                                              |
 *              |                                              |
 *              |                                              |
 *              |    tSRX1         tScrX                       |
 *              |        |  tSRX2      |                       |
 *              |________V____V________V                       |
 *       tTopY->|                      |                       |
 *              | active               |                       |
 *              | screen               |                       |
 *     tSRY1--->|        +----+        |                       |
 *              |        |    |<----------- Scrolling Region   |
 *     tSRY2--->|        +----+        |                       |
 *       tScrY->|______________________|                       |
 *              |                                              |
 *              |                                              |
 *              |                                              |
 *              |                                              |
 *              |                                              |
 *              |                                              |
 *       tBufY->|______________________________________________|
 *
 * So tBufX and tBufY define the absolute limits of our buffer, tBuffer.
 * tTopY defines the top of the screen, and can take any value from
 * 0 to tBufY. Note as tTopY gets close to the bottom, the screen wraps back
 * to the start, and the screen will actually be "split" - appearing partially
 * at the start, and partially at the end of the buffer.
 *
 * tScrX and tScrY are relative values. tScrY is the number of rows for the
 * "active" screen. If tScrY is set to 10, for example, then the active
 * screen spans from row (tTopY) to (tTopY+9). It's a similar deal for
 * tScrX, except tScrX will usually be equal to tBufX.
 * Note that if the cursor reaches the X position of tScrX, it will wrap
 * back around to column 0.
 *
 * tSR?? define the bounds of the current scrolling region. These are relative
 * values like tScrX and tScrY.
 *
 * tCurX and tCurY are "screen coordinate" values for the current cursor position.
 * tCurX=0 and tCurY=0 corresponds to the top left of the active screen.
 *
 * To help you with all this stuff, you'll find below a bunch of macros to
 * help coordinate your terminal access. For the most part, positive Y values
 * in the below macros will access the current screen, and negative Y values
 * will access the scrollback buffer. There are also macros to give you
 * the screen and buffer limits. Note that Y=0 corresponds to the top row
 * of the active screen, or tTopY.
 *
 * Now just a quick note on characters. Each character is composed of a long
 * unsigned integer. The LSB (8 bits) is the ANSI character. The rest are left
 * as general attribute bytes and can be customized for your particular needs.
 * To facilitate this, you'll find above Foreground, background, and effect
 * masks and generators. You can define how many bits you assign to your
 * colour bank and everything will adjust accordingly. The colour bank in
 * the TBTERMBUF structure is for your convenience; take it out if you don't
 * want to use it. It's intended to map the value found in tBuffer to the actual
 * character colour when printed to the screen. It's contained in the sctructure
 * so that it may be personalized for each terminal independently.
 *
 * And how about a note on hilighting. The values for tHLStartX etc follow
 * the same positive/negative coordinate system as the macros below. IE:
 * positive Y values correspond to rows within the active screen; negative
 * Y values correspond to rows within the scrollback buffer. Y=0 corresponds
 * to the top row of the active screen, or tTopY. With hilighting, it is assumed
 * that the END HIGHLIGHT POSITION corresponds to the LAST HILIGHT ELEMENT **PLUS ONE**.
 * Therefore, to set the hilight to null, set the start and end coords to
 * the same value.
 *
 * Well, I hope you have it, kuz I'm tired of typing. Good luck.
 */

/* TB_GETCHAR returns the unsigned long element at (x,y). This macro can
 * access both screen (y>=0) and scrollback (y<0) regions. Note it is assumed
 * y is between TB_GETYMIN() and TB_GETYMAX(). */
#define TB_GETCHAR(buf,x,y) \
	(*( ((buf->tTopY+y)>=buf->tBufY)? \
			(buf->tBuffer+x+(buf->tTopY+y-buf->tBufY)*buf->tBufX): \
			((buf->tTopY+y)<0)?(buf->tBuffer+x+(buf->tTopY+y+buf->tBufY)*buf->tBufX):\
			(buf->tBuffer+x+(buf->tTopY+y)*buf->tBufX) ))

/* TB_GET?MIN and TB_GET?MAX return absolute min/max values that you can then
 * use as x/y values. */
#define TB_GETYMIN(buf) (buf->tScrY-buf->tBufY)
#define TB_GETYMAX(buf) (buf->tScrY-1)
#define TB_GETXMIN(buf) (0)
#define TB_GETXMAX(buf) (buf->tBufX-1)

/* TB_IS_SCR_SPLIT() returns 1 if the current screen is split at the
 * wrap-around point in the circular buffer. Otherwise, it returns 0. */
#define TB_IS_SCR_SPLIT(buf) \
	((buf->tTopY+buf->tScrY)>=buf->tBufY)

/* TB_GETCHARADDR returns the address (pointer) of the element at (x,y). The
 * same restrictions apply as for TB_GETCHAR above. */
#define TB_GETCHARADDR(buf,x,y) \
	(((buf->tTopY+y)>=buf->tBufY)? \
		(buf->tBuffer+x+(buf->tTopY+y-buf->tBufY)*buf->tBufX): \
		((buf->tTopY+y)<0)?(buf->tBuffer+x+(buf->tTopY+y+buf->tBufY)*buf->tBufX):\
		(buf->tBuffer+x+(buf->tTopY+y)*buf->tBufX))

/* TB_SETATTR* set the current attribute colours and effect */
#define TB_SETATTRFCOLOUR(buf,x)  \
	(((buf->tCurrentAttribute|TB_FCOLOURMASK)^TB_FCOLOURMASK)|TB_MAKEFCOLOUR(x))
#define TB_SETATTRBCOLOUR(buf,x)  \
	(((buf->tCurrentAttribute|TB_BCOLOURMASK)^TB_BCOLOURMASK)|TB_MAKEBCOLOUR(x))
#define TB_SETATTREFFECT(buf,x)  \
	(((buf->tCurrentAttribute|TB_EFFECTMASK)^TB_EFFECTMASK)|TB_MAKEEFFECT(x))

/* TB_SETNOTIFYFN sets the notify (callback) function */
#define TB_SETNOTIFYFN(buf,fn) (buf->tNotifyFn=fn)

/* TB_SETHTAB sets the horizontal tab */
#define TB_SETHTAB(buf,x) (buf->tHTab=x)

/* Function pool */
TBTERMBUF *tbAllocTermBuf(unsigned long p_ID, long p_BufX,long p_BufY,long p_ScrX,long p_ScrY);
void tbFreeTermBuf(TBTERMBUF *p_TermBuf);
TBTERMBUF *tbReAllocTermBuf(TBTERMBUF *p_TermBuf,long p_BufX,long p_BufY,long p_ScrX,long p_ScrY);
void tbPutChar(TBTERMBUF *p_TermBuf, unsigned char p_char);
void tbPutCharReverse(TBTERMBUF *p_TermBuf, unsigned char p_char);
void tbSetFColour(TBTERMBUF *p_TermBuf, unsigned long p_colour);
void tbSetBColour(TBTERMBUF *p_TermBuf, unsigned long p_colour);
void tbSetEffect(TBTERMBUF *p_TermBuf, unsigned long p_effect);
void tbSetCursor(TBTERMBUF *p_TermBuf, unsigned long p_CurX, unsigned long p_CurY);
void tbClearScreen(TBTERMBUF *p_TermBuf);
//void tbCarridgeReturn(TBTERMBUF *p_TermBuf);
void tbLineFeed(TBTERMBUF *p_TermBuf);
void tbHTab(TBTERMBUF *p_TermBuf);
void tbBackSpace(TBTERMBUF *p_TermBuf);
void tbDelete(TBTERMBUF *p_TermBuf);
void tbCurUp(TBTERMBUF *p_TermBuf);
void tbCurDown(TBTERMBUF *p_TermBuf);
void tbClearLineX(TBTERMBUF *p_TermBuf,long p_Start, long p_End);
void tbCurRight(TBTERMBUF *p_TermBuf);
void tbCurLeft(TBTERMBUF *p_TermBuf);
void tbClearLine(TBTERMBUF *p_TermBuf);
void tbClearRight(TBTERMBUF *p_TermBuf);
void tbClearLeft(TBTERMBUF *p_TermBuf);
void tbScrollDown(TBTERMBUF *p_TermBuf);
void tbScrollUp(TBTERMBUF *p_TermBuf);
void tbInsertChar(TBTERMBUF *p_TermBuf,int p_Spaces);
void tbClearBelow(TBTERMBUF *p_TermBuf);
void tbClearAbove(TBTERMBUF *p_TermBuf);
void tbInsertLine(TBTERMBUF *p_TermBuf,long l_NumLines);
void tbDeleteLine(TBTERMBUF *p_TermBuf,long l_NumLines);
void tbMoveText(TBTERMBUF *p_TermBuf,long p_startX,long p_startY,long p_endX,long p_endY,long p_destX,long p_destY);
void tbCreateUnderscorePen(TBTERMBUF *p_TermBuf,int p_FontHeight);
void tbCursorSave(TBTERMBUF *p_TermBuf);
void tbCursorRestore(TBTERMBUF *p_TermBuf);
void tbTabSet(TBTERMBUF *p_TermBuf,int p_Type, int p_X);
void tbTabClearAll(TBTERMBUF *p_TermBuf);
void tbScrollRight(TBTERMBUF *p_TermBuf);
void tbScrollLeft(TBTERMBUF *p_TermBuf);
void tbHTabReverse(TBTERMBUF *p_TermBuf);
void tbLineFeedUp(TBTERMBUF *p_TermBuf);
int tbVerifyCoordinates(TBTERMBUF *p_TermBuf,int p_X,int p_Y);
void tbStartHilight(TBTERMBUF *p_TermBuf,int p_X,int p_Y);
void tbUpdateHilight(TBTERMBUF *p_TermBuf,int p_X,int p_Y);
void tbClearHilight(TBTERMBUF *p_TermBuf);
BOOL tbIsHilight(TBTERMBUF *p_TermBuf,int p_X,int p_Y);
int tbHilightSize(TBTERMBUF *p_TermBuf);
void tbCopyHilight(TBTERMBUF *p_TermBuf,unsigned char *p_buf);


#endif /* _TERMBUF_H_ */