// *** OpenGTA3 ***
// 3D engine related stuff (non-Renderware)
#include "stdafx.h"
#include "ogEngine.h"

extern RxPipeline ** mapPipeline = (RxPipeline **)0xC02D24;

DWORD * _C02CB0 = (DWORD *)0xC02CB0;

struct RxNodeDefinition;
struct RxLockedPipe;
struct RxNodeDefinition;
struct RxD3D9ResEntryHeader;
struct RwResEntry;
struct RxPipelineNode;

typedef bool (*RxD3D9AllInOneInstanceCallBack)(void *object, RxD3D9ResEntryHeader *resEntryHeader, bool reinstance);
typedef bool (*RxD3D9AllInOneReinstanceCallBack)(void *object, RwResEntry *resEntry, RxD3D9AllInOneInstanceCallBack instanceCallback);
typedef void (*RxD3D9AllInOneRenderCallBack)(RwResEntry *repEntry, void *object, BYTE type, DWORD flags);


RxLockedPipe * (*RxPipelineLock)(RxPipeline * pipe) = (RxLockedPipe * (__cdecl *)(RxPipeline *))0x806990;
RxNodeDefinition * (*RxNodeDefinitionGetD3D9AtomicAllInOne)() = (RxNodeDefinition *(__cdecl *)())0x7582E0;
bool (*RxLockedPipeUnlock)(RxLockedPipe *) = (bool (__cdecl *)(RxLockedPipe *))0x805F40;
RxLockedPipe * (*RxLockedPipeAddFragment)(RxLockedPipe *pipeline,DWORD *firstIndex, RxNodeDefinition *nodeDef0, ...) = 
	(RxLockedPipe * (__cdecl *)(RxLockedPipe *, DWORD *, RxNodeDefinition *, ...))0x806BE0;
RxPipelineNode * (*RxPipelineFindNodeByName)(RxPipeline *pipeline, const char *name, RxPipelineNode *start, DWORD *nodeIndex) = 
	(RxPipelineNode * (__cdecl *)(RxPipeline *, const char *, RxPipelineNode *, DWORD *))0x806B30;

void (*RxD3D9AllInOneSetReinstanceCallBack)(RxPipelineNode * node, RxD3D9AllInOneReinstanceCallBack cb) = 
	(void (__cdecl *)(RxPipelineNode *, RxD3D9AllInOneReinstanceCallBack))0x7573A0;
void (*RxD3D9AllInOneSetRenderCallBack)(RxPipelineNode *node, RxD3D9AllInOneRenderCallBack callback) = 
	(void (__cdecl *)(RxPipelineNode *, RxD3D9AllInOneRenderCallBack))0x7573E0;


//bool (*mapPipeRenstanceCallback)(void *object, RwResEntry *resEntry, RxD3D9AllInOneInstanceCallBack instanceCallback) = 
//	(bool (__cdecl *)(void *, RwResEntry *, RxD3D9AllInOneInstanceCallBack))0x5D8490;
//bool (*mapPipeRenderCallback)(RwResEntry *repEntry, void *object, BYTE type, DWORD flags) =
//	(bool (__cdecl *)(RwResEntry *, void *, BYTE, DWORD))0x5D9900;
RxD3D9AllInOneReinstanceCallBack mapPipeRenstanceCallback = (RxD3D9AllInOneReinstanceCallBack)0x5D8490;
RxD3D9AllInOneRenderCallBack mapPipeRenderCallback = (RxD3D9AllInOneRenderCallBack)0x5D9900;


// Initialize environment mapping pipelines
// NOTE: таких функций три штуки, отличающихся ID и коллбэками. Имеет смысл сделать одну
bool allocMapPipe () { // 5DA020/5D5AC0
	// *mapPipeline = InitPipeline ();
	*mapPipeline = RxPipelineCreate ();
	if (!*mapPipeline) 
		return false;

	RxLockedPipe * lp = RxPipelineLock (*mapPipeline);
	if (lp) {
		RxNodeDefinition * nodedef = RxNodeDefinitionGetD3D9AtomicAllInOne ();
		if (RxLockedPipeUnlock (RxLockedPipeAddFragment (lp, NULL, nodedef, NULL))) {
			// TODO: после расписывания структуры поставить нормальную конструкцию
			RxPipelineNode * n = RxPipelineFindNodeByName (*mapPipeline, *(const char **)nodedef, NULL, NULL);
			// RxD3D9AllInOneSetInstanceCallBack (RxD3D9AllInOneGetInstanceCallBack (n));
			RxD3D9AllInOneSetReinstanceCallBack (n, mapPipeRenstanceCallback);
			RxD3D9AllInOneSetRenderCallBack (n, mapPipeRenderCallback);
			(*mapPipeline)->pluginId = 0x53F2009A;
			(*mapPipeline)->pluginData = 0x53F2009A;
			// if (!isEnvironmentMappingSupported ()) return false;
			memset (_C02CB0, 0, 26*4);
			debug ("environment map pipeline created \n");
			return true;
		}
	} 

	if (*mapPipeline)
		RxPipelineDestroy (*mapPipeline);
	return false;
}

void freeMapPipe () { // >> 5DA130 (2)
	if (*mapPipeline) {
		RxPipelineDestroy (*mapPipeline);
		*mapPipeline = NULL;
	}
	debug ("environment map pipeline destroyed\n");
}

