// функции и переменные, которые еще не переписаны, но которые надо вызывать
// по мере реализации, они выносятся из этого файла

extern FILE * logfile;


extern void (*releaseModel) (DWORD index);	// >> 4089A0 (89)
extern void (*_40E120)(DWORD _a0);	// >>40E120 (8)
extern int (*getIfpIndexByName)(char * name); // >> 4D3990 (62)

extern void (*checkCheatcode)(int key);	// >> 439AF0 (1)

extern void (*_53C500)(int player, DWORD _a4);	// 53C500 (5)
extern void (*resetTimers) ();		// >>561AA0 (11)
extern void (*_561B10)(); // >> 561B10 (13)

extern void (*readTrackFiles)();	// >> 6F7440 (3)



// day time
extern short *	currentTimeSeconds;
extern char *	currentTimeMinutes;
extern char *	currentTimeHours;
extern char *	currentMonthDay;
extern char *	currentMonth;
extern float *	daylightLightingState;
extern void		calculateDaylightLightingState ();	// >>  5D7F80 (XREF: 5D8050)

// set some text-related flags
extern void _719380 (float scaleX, float scaleY); // >> 719380 (47)
extern void _7193A0 (float scaleX, float scaleY); // >> 7193A0 (13)
extern void _719430 (DWORD color); // >> 719430 (71)	setTextColor
extern void _719490 (BYTE a0); // >> 717490 (55)
extern void _7194D0 (float c); // >> 7194D0 (27)
extern void _7194E0 (float f); // >> 7194E0 (21)
extern void _719500 (float f); // >> 719500 (5)			setTextAlpha 
extern void _719510 (DWORD color); // >> 719510 (35)	setTextBackground
extern void _719570 (BYTE a0); // >> 719570 (14)
extern void _719590 (BYTE a0); // >> 719590 (45)
extern void _7195B0 (BYTE a0); // >> 7195B0 (32)
extern void _7195C0 (BYTE a0, BYTE a4); // >> 7195C0 
extern void _719610 (BYTE a0); // >> 719610  (60)

extern void (*_719800)(); // >> 719800 (10)
extern void (*_71A820)(float, float, const TCHAR *);	// >> 71A820 (какой-то drawText)

extern void (*_727350)(); // >> 727350 (12)	reset2D


// 2D graphics (TODO: move to og2D.h or something)
union RGBA;

extern void (*_727420) (float * coords, RGBA * rgba1, RGBA * rgba2, RGBA * rgba3, RGBA * rgba4); // >> 727420 (9)
extern void drawRect (float * coords, RGBA * rgba); // >> 727B60 (62)

extern void _734750 ();	// prepare render state for 2D

extern void * vertices; // C80468 (RwD3DVertex9[8])

extern int (*getTextLineCount) (float x, float y, char * text); // 71A5E0 (4)
extern void (*_71A700)(float x, float y, const TCHAR * text); // >> 71A700 (72) ?? putText ?

extern int (*txdIndexByName) (char * name);	// >> 731850 (47)
extern void (*txdSetCurrent)(DWORD index);	// >> 7319C0 (32)
///extern DWORD (*txdAddReference)(DWORD index); // >> 731A00 (23)
extern int (*txdAdd)(char * name); // >> 731C80 (21)

// find TXD in pool; create it if not found
extern int	txdIndexByNameAlways (char * name);

extern void		saveTexDictionary ();		// >> 7316A0 (29)
extern void		restoreTexDictionary ();	// >> 7316B0 (36)

// ** custom plugins **
extern DWORD * pl253F2F8_TK;

// ** Skeleton **
enum RsEventStatus {
    rsEVENTERROR,
    rsEVENTPROCESSED,
    rsEVENTNOTPROCESSED
};

enum RsEvent {
    rsCAMERASIZE			= 0,			
    rsCOMMANDLINE			= 1,			
    rsFILELOAD				= 2,
    rsINITDEBUG				= 3,
    rsINPUTDEVICEATTACH		= 4,	
    rsLEFTBUTTONDOWN		= 5,
    rsLEFTBUTTONUP			= 6,
    rsMOUSEMOVE				= 7,
    rsMOUSEWHEELMOVE		= 8,
    rsPLUGINATTACH			= 9,
    rsREGISTERIMAGELOADER	= 10,
    rsRIGHTBUTTONDOWN		,
    rsRIGHTBUTTONUP			,
    rsRWINITIALIZE			= 21,			
    rsRWTERMINATE			= 22,			
    rsSELECTDEVICE			= 23,			
    rsINITIALIZE			= 24,
    rsTERMINATE				= 25,	
	rsIDLE					= 26,	// do all work
    rsRENDER				= 27,	// idle without game mechanics processing
    rsKEYDOWN				= 28,
    rsKEYUP					= 29,
    rsQUITAPP				= 30,
    rsPADBUTTONDOWN			= 31,
    rsPADBUTTONUP			= 32,
    rsPADANALOGUELEFT		= 33,
    rsPADANALOGUELEFTRESET	= 34,
    rsPADANALOGUERIGHT		= 35,
    rsPADANALOGUERIGHTRESET	= 36,
    rsPREINITCOMMANDLINE	= 37,
    rsACTIVATE				= 38,
    rsSETMEMORYFUNCS
};

extern RsEventStatus (*RsEventHandler)(RsEvent event, void *param); // >> 619B60


// ** RenderWare

struct RsInputDevice {
	int		type;
	int		used;
	void *	handler;
};

struct PsGlobalType {
	HWND		window;
	HINSTANCE	instance;
	DWORD		fullscreen;
	float		lastMousePosX;
	float		lastMousePosY;
	// ... TODO: more fields here
};

struct RsGlobalType {
	char *	appName;
	int		maximumWidth;
	int		maximumHeight;
	int		frameLimit;
	int		quit;
	PsGlobalType *	ps;
	RsInputDevice	keyboard;
	RsInputDevice	mouse;
	RsInputDevice	pad;
};

extern RsGlobalType * rsGlobal;

struct RwTexture;
struct RwTexDictionary;
struct RwStream;
struct RpAtomic;
struct RwFrame;
struct RpClump;
struct RpSkin;
struct RpGeometry;
struct RwMatrix;

extern int (*RwEngineGetCurrentSubSystem)(); // >> 7F2C60 (4)
extern void  (*RwTextureDestroy)(RwTexture *); // >> 7F3820 (91)
extern DWORD (*RwTexDictionaryCreate)(); //  7F3600 (8)
extern void  (*RwTexDictionaryDestroy)(DWORD dict); // >> 7F36A0 (8)
extern DWORD (*RwTexDictionaryGetCurrent)(); // 7F3A90 (6)
extern void	 (*RwTexDictionarySetCurrent)(DWORD txd); // 7F3A70 (6)
// extern DWORD (*RwTexDictionaryForAllTextures)(DWORD dict, DWORD (*callback)(RwTexture *, void * param), void * param); // >> 7F3730 (14)
extern RwTexture * (*RwReadTexture)(char * name, char * maskName);// >> 7F3AC0
extern DWORD (*RwTexDictionaryAddTexture)(DWORD dict, RwTexture * tex); // >> 7F3980 (16)
extern RwTexture *(*RwTexDictionaryRemoveTexture)(RwTexture * texture);	// >> 7F39C0 (1/2)

typedef RwTexture *(*RwTextureCallBackFind)(const char *name);
typedef RwTexture *(*RwTextureCallBackRead)(const char *name, const char *maskName);
typedef RwTexture *(*RwTextureCallBack)(RwTexture *texture, void *pData);

extern bool (*RwTextureSetFindCallBack)(RwTextureCallBackFind callBack);
extern bool (*RwTextureSetReadCallBack)(RwTextureCallBackRead callBack);

extern RwTexture * (*RwTexDictionaryFindNamedTexture)(RwTexDictionary * dict, const char * name); // >> 7F39F0 (14)
extern const RwTexDictionary *(* RwTexDictionaryForAllTextures)(const RwTexDictionary * dict, RwTextureCallBack fpCallBack, void *pData);
// extern void * (*RwStreamOpen)(int type, int accessType, void * data);	// >> 7ECEF0 (23)
// extern void (*RwStreamClose)(void * stream, void * data); // 7ECE20 (52)
// extern int (*RwStreamFindChunk)(void * stream, int type, int * lengthOut, int * versionOut); // >> 7ED2D0 (92)

extern void * (*RpClumpStreamRead)(void * stream); // >> 74B420 (9)
extern void (*RpClumpForAllAtomics)(void *, RpAtomic * (__cdecl *)(RpAtomic *, void *), void *); // >> 749B70 (82)
extern void (*RpClumpDestroy)(void *); // >> 74A310 (22)
extern RpClump * (*RpClumpClone)(RpClump *); // >> 749F70 (1)

RpClump * RpClumpAddAtomic (RpClump * c, RpAtomic * a);
RpClump * RpClumpRemoveAtomic (RpClump * c, RpAtomic * a);

extern bool (* RpAtomicDestroy)(RpAtomic *); // >> 749DC0 (26)
extern RpAtomic * (*RpAtomicClone)(RpAtomic *); // >> 749E60 (18)
extern RpAtomic * (*RpAtomicSetFrame)(RpAtomic *, RwFrame *); // 74BF20 (34)

extern RwFrame * (*RwFrameCreate)(); // >> 7F0410 (28)
extern bool (*RwFrameDestroy)(RwFrame *); // >> 7F05A0 (30)

extern RpSkin * (*RpSkinGeometryGetSkin)( RpGeometry *geometry ); // >> 7C7550 (32)

typedef RwFrame *(*RwFrameCallBack)(RwFrame *frame, void *data);
extern RwFrame * (*RwFrameForAllChildren)(RwFrame * frame, RwFrameCallBack callBack, void *data);	// >> 7F0DC0 (36)
extern RwFrame * (*RwFrameForAllObjects)(RwFrame * frame, RwFrameCallBack callBack, void *data);	// >> 7F1200 (44)
extern RwFrame * (*RwFrameTransform)(RwFrame *, RwMatrix *, int combineOp); // >> 7F0F70 (5)
extern RwFrame * (*RwFrameAddChild)(RwFrame * frame, RwFrame * child);  // >> 7F0B00 (9)
extern RwFrame * (*RwFrameUpdateObject)(RwFrame *);
extern RwMatrix * (*RwFrameGetLTM)(RwFrame *);
extern RwFrame * (*RwFrameRemoveChild)(RwFrame *child);



//=============================================================================
// texture dictionaries
// TODO: возможно, тоже нуждается в реорганизации, но позже
#pragma pack(push,1)
struct RwTexDictionary;
class CTxdEntry {
public:
	CTxdEntry (char * name);

	void * operator new (size_t);
	
// protected:
	RwTexDictionary * dictionary;
	short	usageCount;
	short	parentIndex;
	short	__pad;
	DWORD	hash;
};
#pragma pack(pop)
extern DWORD	getDefaultTxd (int n);	// >> 7316D0 (XREF: 5A4220)
extern void initTxdPool ();
extern bool txdGarbageCollect ();	// >> 732060 (XREF: sub_53C900)
extern bool txdLoad (int index, char * filename);	// >> 7320B0 (14)
extern bool txdRead (int index, RwStream * stream);	// >> 731DD0 (2)
extern RwTexDictionary * txdReadChunk (RwStream * stream); // >> 730FC0 (2)
extern void txdAddRef (int index);
extern void txdRelease (int index);
//=============================================================================
// configuration files
// TODO: после того, как форматы файлов будут полностью разобраны, 
//	будет продумана структура бинарного конфига и сделана одна единственная функция,
//	которая будет его загружать.
//	Для совместимости с текстовыми форматами, будет сделан выносной компилятор
//	Возможно, но не обязательно, будет сделан визуальный редактор.
extern void readGameConfig (TCHAR * filename);	// >> 5B9030 (1)

//=============================================================================
// assorted 3D
extern bool allocMapPipe (); // 5DA020/5D5AC0
extern void freeMapPipe (); // >> 5DA130 (2)
