#pragma once
//===========================================================================//
// File:	 Script.hpp														 //
// Project:  GOSScript				                                         //
// Contents: Script Processing												 //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 02/27/98  AG    Created													 //
//---------------------------------------------------------------------------//
// Copyright (C) 2000, Microsoft, Inc.										//
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//
#include <GameOS\GameOS.hpp>
#include <GameOS\ToolOS.hpp>
#include "GOSScriptHeaders.hpp"
#include <string.h>
#include <mbstring.h>
#include <mbctype.h>
#include <math.h.>
#include <stdio.h>
#include <stdlib.h>
#include "LinkedList.hpp"
#include "Surface.hpp"
#include "SurfaceManager.hpp"
#include "GAF.hpp"
#include "Font.hpp"
#include "Pane.hpp"

#pragma warning(disable: 4514)

//
// Set this define to 1 if gosScript is being ported to something other than
// GameOS.
//
#define DISTRIBUTED_GOSSCRIPT 0

//
// Mail can be nested up to 32 times
//
#define MAX_MAILSTACK 32



//
//
// Must be called at startup, init the engine
//
void InitScripts();
//
// Must be called once at exit, free all memory
//
void DestroyScripts();
//
// Called during the game execution to run scripts
//
void ScriptsExecute();
void __stdcall ScriptsUpdate( int Priority );	//Draw
//
// Used for errors and spews
//
#define GROUP_SURFACE "GameOS_ScriptsSurface"					// SPEW works like this:   GameOS_Scripts*

#define GROUP_SCRIPTS "GameOS_ScriptsInternal"
#define GROUP_FROMSCRIPTS "GameOS_ScriptsOutput"
#define GROUP_VERBOSESCRIPTS "GameOS_ScriptsVerbose"
//
// Maximum length of lines
//
const int SCRIPT_MAX_LINE_LENGTH=1024;
const int SCRIPT_STRING_LENGTH=4096;

//
// Mouse button status
//
typedef enum
{
	BUTTON_FREE,
	BUTTON_PRESSED,
	BUTTON_HELD,
	BUTTON_RELEASED,
	BUTTON_CLICKED,
	BUTTON_DCLICKED,
} BUTTON_STATES;



//// Routine numbers (see strings in ScriptExpressions.cpp)
//
enum ROUTINES
{
	ROUTINE_GETKEYSTATE=0,
	ROUTINE_GETKEYPRESSED,
	ROUTINE_SETVOLUME,
	ROUTINE_SETPANNING,
	ROUTINE_SETFREQUENCY,
	ROUTINE_SETPROPERTIES,
	ROUTINE_GETVOLUME,
	ROUTINE_GETPANNING,
	ROUTINE_GETFREQUENCY,
	ROUTINE_GETSTATUS,
	ROUTINE_GETSIZE,
	ROUTINE_ABSOLUTEVALUE,
	ROUTINE_GETCHAR,
	ROUTINE_CHAR,
	ROUTINE_GETPIXEL,
	ROUTINE_GETHEIGHT,
	ROUTINE_GETWIDTH,
	ROUTINE_CALLBACK,
	ROUTINE_GETMESSAGE,
	ROUTINE_GETTIME,
	ROUTINE_GETTIMEX,
	ROUTINE_GETPRINT3DWIDTH,
	ROUTINE_GETPRINT3DHEIGHT,
	ROUTINE_GETPRINT3DPOSX,
	ROUTINE_GETPRINT3DPOSY,
	ROUTINE_GOTFOCUS,
	ROUTINE_MAKEINT,
	ROUTINE_EXISTS,
	ROUTINE_GETRESX,
	ROUTINE_GETRESY,
	ROUTINE_PACKCOLOR,
	ROUTINE_TOP,
	ROUTINE_BOTTOM,
	ROUTINE_NEXT,
	ROUTINE_PREV,
	ROUTINE_ADD,
	ROUTINE_REMOVE,
	ROUTINE_LENGTH,
	ROUTINE_EMPTY,
	ROUTINE_COUNTJS,
	ROUTINE_JSGETAXIS,
	ROUTINE_JSGETBUTTON,
	ROUTINE_COUNTBUTTONS,
	ROUTINE_ISAXISVALID,
	ROUTINE_MAIL,
	ROUTINE_GETCTRLCHAR,
	ROUTINE_QUERYCHAR,
	ROUTINE_LAUNCH,
	ROUTINE_SETPOINTER,
	ROUTINE_JSPOLL,
	ROUTINE_GETKEY,
	ROUTINE_DBLCLICK,
//
// This MUST be the last entry
//
	LAST_ROUTINE
};
//
// Keyword numbers (see strings in ScriptExpressions.cpp)
//
typedef enum
{
	KEY_IF=0,
	KEY_ELSE,
	KEY_INT,
	KEY_OBJECT,
	KEY_SPEW,
	KEY_FOR,
	KEY_WHILE,
	KEY_DO,
	KEY_BREAK,
	KEY_CONTINUE,
	KEY_BITMAP,
	KEY_FONT,
	KEY_SOUND,
	KEY_BLIT,
	KEY_POSITION,
	KEY_PLAY,
	KEY_LOOP,
	KEY_LINE,
	KEY_LLINE,
	KEY_STRING,
	KEY_KILL,
	KEY_PRINT_POSITION,
	KEY_PRINT,
	KEY_PRINT_BITMAP,
	KEY_PRINT_FONT,
	KEY_PRINT_MARGINS,
	KEY_COLORKEY,
	KEY_SCRIPT_RUN,
	KEY_SCRIPT_END,
	KEY_SCRIPT_PAUSE,
	KEY_SCRIPT_CONTINUE,
	KEY_FOCUS,
	KEY_UNFOCUS,
	KEY_CUBE,
	KEY_MOVIE,
	KEY_STOPMEDIA,
	KEY_GAF,
	KEY_SETFRAME,
	KEY_BITMAPCREATE,
	KEY_BITMAPCLEAR,
	KEY_BITMAPREFRESH,
	KEY_RANDOM,
	KEY_DEBUG,
	KEY_PANE,
	KEY_SCALE,
	KEY_ROTATE,
	KEY_ORIGIN,
	KEY_COLOR,
	KEY_ALPHAMODE,
	KEY_RENDER,
	KEY_PANE_CREATE,
	KEY_UPDATE,
	KEY_REFRESH,
	KEY_WRAP,
	KEY_NOCONSUME,
	KEY_WRAPWORD,
	KEY_WRAPLETTER,
	KEY_WRAPNONE,
	KEY_FILL,
	KEY_FORCEEXEC,
	KEY_RETURNFROMSECTION,
	KEY_INITIALIZE,
	KEY_DRAWRECT,
	KEY_DRAWFRAME,
	KEY_PENCOLOR,
	KEY_PRINT3D_POSITION,
	KEY_PRINT3D_MARGINS,
	KEY_PRINT3D_ATTRIBUTES,
	KEY_FONT3D,
	KEY_PRINT3D,
	KEY_CLEARZBUFFER,
	KEY_TEXTUREHEAP,
	KEY_TERMINATE,
	KEY_ACTIVATE,
	KEY_DEACTIVATE,
	KEY_STRINGRESOURCE,						// SET LOCAL RESOURCE
	KEY_ASSIGN,
	KEY_DRAWFRAMELOCAL,
	KEY_DRAWRECTLOCAL,
	KEY_LPRINT3D_MARGINS,
	KEY_LPRINT3D_POSITION,
	KEY_FLOAT,
	KEY_LIST,
	KEY_SWITCH,
	KEY_CASE,
	KEY_DEFAULT,
	KEY_JSGETNAME,
	KEY_MAKEABSOLUTE,
	KEY_GETSCRIPTINFO,
	KEY_SETCARET,
	KEY_ENABLEIME,
	KEY_GETCLIPBOARD,
	KEY_SETCLIPBOARD,
	KEY_PAUSEMEDIA,
	KEY_CONTINUEMEDIA,
	KEY_TOGGLEIME,
	KEY_PRECISION,
//
// Special types (++ and --)
//
	KEY_INC,
	KEY_DEC,
//
// Now the internal types ( KEY_TYPE+VAR_TYPE )
//
	KEY_TYPE,
//
// This MUST be the last entry
//
	LAST_KEYWORD
} KEYWORDS;

typedef enum
{
	KVAR_LINECOLOR
} KEYVARIABLES;

//
// Messages used in functions
//
typedef enum
{
	MSG_GUI_INIT,
	MSG_GUI_MAILBOX,
	MSG_GUI_FOCUS,
	MSG_GUI_UNFOCUS,
	MSG_GUI_ACTIVATE,
	MSG_GUI_DEACTIVATE,
	MSG_REGION_ENTERED,
	MSG_REGION_EXITED,
	MSG_LBUTTON_UPDATE,
	MSG_MBUTTON_UPDATE,
	MSG_RBUTTON_UPDATE,
	MSG_AUX1BUTTON_UPDATE,
	MSG_AUX2BUTTON_UPDATE,
	MSG_WHEEL_MOVED,
	MSG_GUI_CREATE,
	MSG_GUI_EXECUTE,
	MSG_GUI_DESTROY,
	MSG_GUI_DRAW,
	MSG_GUI_CHAR,
	MSG_GUI_PAUSE,
	MSG_GUI_CONTINUE,
	MSG_GUI_RESOLUTION,
//
// This MUST be the last entry
//
	LAST_MESSAGE
} MESSAGES;

//
// Possible states the compiler may be in after an #if, #else, #endif
//
enum IFSTATE { IFNormal=0, IFDo2Else, IFDo2Endif, IFSkip2Else, IFSkip2Endif, IFIgnore2Endif };



//
// Structure used to hold processed lines in buffer
//
//
//
//
#pragma pack(push,1)
typedef struct
{
	WORD	LineNumber;
	WORD	LineLength;
	char*	FileName;
	DWORD	LineFlags;				// Used by different keywords for different things.
	BYTE	Keyword;
	char	Line[0];

} LINEINFO;
#pragma pack(pop)



class gosScript_List;
//
//
//
// Variables defined in objects
//
//
//
enum VAR_TYPE { VAR_UNKNOWN=KEY_TYPE, VAR_INT, VAR_STRING, VAR_POSITION, VAR_BITMAP, VAR_OBJECT, VAR_FONT, VAR_SOUND, VAR_CUBE, VAR_MOVIE, VAR_GAF, VAR_PANE, VAR_FONT3D, VAR_FLOAT, VAR_LIST, VAR_STRANGE };
enum VAR_SCOPE { SCOPE_LOCAL, SCOPE_OBJECT, SCOPE_GLOBAL };
#pragma pack(push,4)
typedef struct _VARIABLE
{
	_VARIABLE*	pNext;			// Pointer to next variable
	union
	{
		int					Value;			// int
		float				fValue;			// float
		HGOSSURFACE			Surface;		// Bitmap, font
		gos_Pane *			Pane;			// A pane
		gosScript_List	   *pList;			// 
		HGOSVIDEO			Video;			// Video
		HGOSAUDIO			Sound;			// Sound
		HGOSGAF				Gaf;			// A gos animation file
		char*				pString;		// Pointer to a string (Pointer to an array of pointers when in an array)
		POSITION*			pPosition;		// Pointer to a position (or start of an array of positions)
		CUBE*				pCube;
		HGOSFONT3D			pFont3d;
		int*				pValues;		// Pointer to array of ints
		float*				pfValues;		// Pointer to array of floats
		HGOSGAF*   			pGAFs;			// Pointer to array to gos animation files
		HGOSSURFACE*		pSurfaces;		// Pointer to array of surfaces
		HGOSAUDIO*			pSounds;		// Pointer to array of Sounds
		HGOSVIDEO*			pVideos;		// Pointer to array of Movies
		char*				pStrings;		// Pointer to array of string pointers
		POSITION**			pPositions;
		CUBE**				pCubes;
		gos_Pane **			pPanes;			// Pointer to array of pane pointers
		gosScript_List	  **pLists;			// 
		HGOSFONT3D*			pFont3ds;
	};
	WORD		ArraySize;		// When arraysize is !=0 the values in the union become pointers to arrays of values
	BYTE		Type;			// Type
	BYTE		Unused;			// Padding
	WORD		Hash;			// Hash value					: 0,1 Important order!
	BYTE		NameLength;		// Length of variable name		: 2
	char		Name[1];		// Variable name				: 3
} VARIABLE;

//
// Variables registered by the client application
//
//
typedef struct _REGVAR
{
	_REGVAR*		pNext;
	BYTE			NameLength;				// Length of variable name
	BYTE			Type;
	WORD			ArraySize;
	int				Instance;
	union
	{
		int					Value;			// int
		HGOSSURFACE			Surface;		// Bitmap, font
		gos_Pane *			Pane;			// a single Pane
		HGOSAUDIO			Sound;			// Sound
		char*				pString;		// Pointer to a string (Pointer to an array of pointers when in an array)
		POSITION*			pPosition;		// Pointer to a position (or start of an array of positions)

		int*				pValues;		// Pointer to array of values
		HGOSSURFACE*		pSurfaces;		// Pointer to array of surfaces
		HGOSAUDIO*			pSounds;		// Pointer to array of Sounds
		char*				pStrings;		// Pointer to array of string pointers
		gos_Pane **			pPanes;			// Pointer to array of panes
	};
	char		Name[1];		// Variable name
} REGVAR;




typedef struct _gosScript_ListItem
{
	VARIABLE * pListItemVar;
	_gosScript_ListItem * pNext;
	_gosScript_ListItem * pPrev;
	int Type;
	int Index;

}gosScript_ListItem;

class gosScript_List
{
public:
	int length;
	int index;
	gosScript_ListItem * head;
	gosScript_ListItem * tail;
	gosScript_ListItem * cur;
public:
	gosScript_List();
	~gosScript_List();
	void Add(VARIABLE *, int val = -1, int Index = -1);
	bool Del(VARIABLE *, int val = -1, int Index = -1);
	void Top();
	void Bottom();
	int Empty();
	bool Prev();
	bool Next();
	int Length();
	VARIABLE * GetCurrent();
	int GetCurrentType();
	int GetCurrentIndex();
};


//
// Structure used to hold messages found in functions
//
typedef struct _MESSAGE
{
	_MESSAGE*	pNext;
	MESSAGES	Message;		// Message number
	LINEINFO*	pOffset;		// Pointer in script to message
} MESSAGE;	

//
// Structure used to hold functions found in file (main, button1...)
//
typedef struct _FUNCTION
{
	_FUNCTION*	pNext;
	MESSAGE*	pMessages;		// Pointer to list of messages (CREATE,DRAW...)
	int			NameLength;		// Length of name
	char		Name[1];		// Name of the function (main,button 1 etc..) + 0 at end
} FUNCTION;

//
// Linked list of file names used in script, used while script is
// running for error messages. Used in FILENAME
//
typedef struct _FILENAME
{
	_FILENAME*	pNext;
	char*		LongFileName;
	char		FileName[1];
} FILENAME;

//
// Object variable definition
//
struct _SCRIPT;
//typedef struct _OBJECT
struct OBJECT
{
	OBJECT*		pNext;			// List of Objects
	VARIABLE*	pVariables;		// Pointer to variables defined within object
	_SCRIPT*	pScript;		// Parent Script
#ifdef LAB_ONLY
	double		timeInExecute;	// the amount of time spent performing the execute at the right framerate
	double		timeInDraw;		// the time it took to do the gui_draw
#endif
	int*		AlwaysInRegion; // Always send messages to this object?
	long*		Priority;
	int*		FrameRate;		// how often should execute be called?
	int*		Catchup;		// should the object run execute multiple times to catchup?
	float		LastRan;
	POSITION*	Coordinates;	// The location in space of the upper left corner of the region
	CUBE*		Cube;			// A *simple* region of space for cursor collision
	FUNCTION*	pFunction;		// Function associated with object
	VARIABLE *	pParentVariable;// Variable which holds the objects
	OBJECT *	pParentObject;	// Variable which holds the objects
	DWORD		bActive : 1;		// default is true
	DWORD		bMouseInRegion : 1;	// Is mouse cursor within the region
	DWORD		bInFocus : 1;		// Has this object got the mouse's attention?
	DWORD		bAddToDeathRow : 1;	// Kill this object ASAP
	DWORD		dwAvailIME : 1;	// Is IME available with this object?
	DWORD		dwIMEState : 1;	// State of the IME when focus was lost.
	DWORD		dwDblClicks: 1;	// Does this object accept dblclicks?
	DWORD		dwBlockingFlags;// blocking flags;
	int*		bPosRelative;	// is position relative?
	int			NameLength;		// Length of name object
	char		Name[1];		// Name of object
};

//
// Main script structure used when running
//
typedef struct _SCRIPT
{
	_SCRIPT*		pNext;			// Pointer to next script in list

	OBJECT*			pListofObjects;	// All objects associated with script (including main)

	OBJECT*			pMainObject;	// Pointer to main object

	int				dwPaused;		// 0 = no pause, 1 = halt exe, 2 = halt exe, no draw

	FILENAME*		pFileNames;		// Points to filenames used/included in script

	FUNCTION*		pFunctions;		// Points at functions/messages in script

	char*			pBuffer;		// Buffer containing script

	int				Instance;		// what is the instance?

	DWORD			bAddToDeathRow;	// Kill this script ASAP

} SCRIPT;


//
// Variables used in Save/Restore position
//
typedef struct _SCRIPTSTACK
{
	_SCRIPTSTACK*	pNext;
	int				CurrentLineNumber;
	char*			pStartofLine;
	char*			pFileName;
	char*			pLongFileName;
	char*			pLine;
	SCRIPT*			pScript;
	OBJECT*			pObject;	
	int*			pLastVariable;
	VAR_SCOPE		LastVariableScope;
	VARIABLE*		pTempVariables;
	MESSAGES		CurrentMessage;

} SCRIPTSTACK;
#pragma pack(pop)









#pragma pack(push,1)
//
// Linked list of 'define' keywords, used while preprocessing
//  Used in PROCESS_SCRIPT
//
typedef struct _DEFINE
{
	_DEFINE*	pNext;					// Pointer to next define
	DWORD		Hash;					// Hash of the source text
	BYTE		DefineLength;			// #define length
	BYTE		TextLength;				// Replacement text length
	char		Strings[0];				// Define name text, new text
} DEFINE;
#pragma pack(pop)

//
// Script information used while reading and processing
//
typedef struct _PROCESS_SCRIPT
{
	_PROCESS_SCRIPT*	pParent;		// Pointer to any parent file

	char*			pFileName;			// File name
	char*			pLongFileName;		// Long File Name
	char*			pStart;				// Pointer to start of file in memory
	char*			pEnd;				// Pointer to byte after last
	int				Line;
	char*			Offset;				// Line and offset after #includes

} PROCESS_SCRIPT;





//
// Object array (used for sorting objects)
//
extern OBJECT** pObjectArray;
extern int ObjectNumber;

//
// Object array (used for sorting objects)
//
extern SCRIPT** pScriptArray;
extern int ScriptNumber;

//
// List of all scripts currently loaded.
//
extern SCRIPT*		pListofScripts;			// All scripts loaded into memory

//
// Global variables
//
extern VARIABLE*	pTempVariables;			// Pointer to temp variables defined in non GUI_CREATE messages
extern MESSAGES		CurrentMessage;			// Current message executing (variables only created in GUI_CREATE messages)
extern OBJECT*		pObject;				// Pointer to current object executing
extern SCRIPT*		pScript;				// Pointer to current running script
extern int			CurrentLineNumber;		// Current line number decoding
extern char*		pFileName;				// Current File name
extern char*		pLongFileName;			// Pointer to current FULL file name
extern char*		pLine;					// Pointer within current line
extern char*		pStartofLine;			// Pointer to the start of the current line
extern long*		pLastVariable;			// Pointer to last variable.value found (in GetKeyword)
extern VAR_SCOPE	LastVariableScope;		// Where the last variable was found (in GetKeyword)
extern DWORD		CurrentKeyword;			// Current keyword on line
extern DWORD*		pCurrentLineFlags;
extern BYTE*		pCurrentKeyword;
//
// Script Processing variables
//
extern PROCESS_SCRIPT*	pProcessScripts;		// Scripts being processed (only valid during processing)
extern IFSTATE			IFState;				// 0=Normal, 1=Do code till #else, 2=Do code till #endif, 3=Skip code till #else, 4=Skip code till #endif
extern int				IFNesting;
extern IFSTATE			IFStack[32];			// These are for #IF, #ELSE, #ENDIF
extern int				FirstIFLine;
extern char				Line[SCRIPT_MAX_LINE_LENGTH];	// Decoded line


//
//
//
extern BYTE			FirstKeywordChar[];			// Array of valid start keyword characters
extern BYTE			KeywordChar[];				// Array of valid keyword characters
extern BYTE			DefineChar[];				// Array of valid #define keyword characters


//
//
//
extern POSITION*	ScriptMousePosition;
extern POSITION*	ScriptMousePositionPrev;
extern POSITION*	ScriptMousePositionLocal;
extern int			ScriptMouseButtons;
extern int			OldScriptMouseButtons;


extern DWORD	ModalScripts;					// ModalScripts



extern bool ShowFastPane;						// Show where fast PANE's are being used
extern bool ShowFastRect;						// Show where fast RECT's are being used
extern bool EnableFastPath;						// When true enable fast paths in blade
extern bool DontFastPath;						// Set to 1 to disable 'fast paths'


//
// Compare two strings (0=different, 1=match)
//
int _inline Equals( char* String1, char* String2 )
{
	while( *String2 )
	{
		if( *String1++!=*String2++ )
			return 0;
	}
	return 1;
}
//
// Compare two strings (0=different, 1=match)
//
int _inline Equals( BYTE* String1, char* String2 )
{
	while( *String2 )
	{
		if( *String1++!=*String2++ )
			return 0;
	}
	return 1;
}

//
// Internal routines used during processing
//
void InitFastString();
void DeleteFastStrings();
void ScriptError( char* Error, ...);					// Error in script (FATAL)
void ScriptOutput( char* Message );						// Output a message
SCRIPT * ProcessScript( char* FileName, int Priority, void * instance );		// Read Script into buffer
void InitScriptGlobals();								// Resets all global variables
void CleanUpScripts();									// Clean up scripts
void DeleteVariable( VARIABLE* pTemp );					// Deletes the current variable
void OpenScript( char* FileName );						// Open and process a script
void CloseScript();										// Close current script
void EndScript();										// Clean up and delete current script
char* GetNextLine();									// Returned a pointer to the next line
char* GetString();										// Returns a pointer to the next string
char* GetSimpleString();								// Returns a pointer to the next string, no escape codes or functions - used in #include
int VariableLength();									// Returns the length of a variable and skips over it
int GetKeywordLength( char* Source );					// Returns the length of the keyword that *Source points to
int PeekNextLine();										// Examines the keyword on the next line (used to search for else)
FUNCTION* GetFunction(SCRIPT *, bool checkMe = true);						// Returns next function pointer as an int
DWORD GetPosition( POSITION* Position, DWORD Explicit=0 );// Returns next position
DWORD GetCube( CUBE* cube, DWORD Explicit=0 );			  // Returns next cube

DWORD FindWord();
DWORD FindRoutine();
int GetExpression();									// Returns next expression
char* Keywords[];

void AddVariable( OBJECT * pObj, VAR_SCOPE NewScope, VARIABLE* newVariable );
void CreateDefaultMemberVariables(OBJECT * pObj, DWORD priority);

float FloatGetExpression();								// evaluates a floating point expression
float FloatGetNextExpression();							// grab the next float expression
float FloatGetValue();									// retrieve a single floating point value
float FloatDoOperator(float,float, int);				// perform a mathematical function on floats
int FloatGetOperator();									// get the next operator in an expression

int GetKeyword();										// Returns keyword number pointed to
enum DoCommandRet { RET_END, RET_NOR, RET_BREAK, RET_CONT, RET_RETURN, RET_CASE, RET_DEFAULT };
DoCommandRet DoCommands( bool Execute, bool InCase = false, int NestingLevel = 0);	// Execute commands in the script
int SendScriptMessage( OBJECT* Object, MESSAGES Message );
void SavePosition();							// Save the current script execution position
void RestorePosition();							// Restore a previous script execution position

// jtr added these
void DeleteScriptObject(OBJECT * del_obj);		// remove a specific object by pointer
int NextWordLength();
int GetKeyVariable();
int ExecuteFunction(int func);
bool CheckStringAgainstReserved(char*);
int ResolveVariable(VARIABLE * pVar);
void DrawRect( int TopX, int TopY, int Width, int Height, DWORD Color );
void ScriptDrawLine( int X0, int Y0, int X1, int Y1, DWORD Color );
void ScriptSpewOutput(char * data);
void DestroyDefines();
void InitDefines();
void FlushLineBuffer();
void InitLineBuffer();
void gos_CacheTextDraw( char* String, int Length );
void InitTextCache();
void DestroyTextCache();
void EndofFrameTextCache();
//
// Just less than 64K minimum foot print for gosScripts
//
const int SizeOfProcessBlock=65000;			// 65000 for example
#define SPEWLINE_LENGTH 260


const int MAXCACHE=2048;


#pragma pack(push,1)
typedef struct
{
	char*	Address;
	DWORD	Type;
	DWORD	Hash;							// 0,1 = hash, 2=Length, 3=1st character
} Cache;
#pragma pack(pop)

extern Cache KeywordCache[MAXCACHE];


