#include "stdafx.h"
#include "ogMemory.h"

// in-game pools (TODO: declare here)
CPool ** ptrNodeSinglePool		= (CPool **)0xB74484;
CPool ** ptrNodeDoublePool		= (CPool **)0xB74488;
CPool ** entryInfoNodePool		= (CPool **)0xB7448C;
CPool ** pedPool				= (CPool **)0xB74490;
CPool ** vehiclePool			= (CPool **)0xB74494;
CPool ** buildingPool			= (CPool **)0xB74498;
CPool ** objectPool				= (CPool **)0xB7449C;
CPool ** dummyPool				= (CPool **)0xB744A0;
CPool ** colModelPool			= (CPool **)0xB744A4;
CPool ** taskPool				= (CPool **)0xB744A8;
CPool ** eventPool				= (CPool **)0xB744AC;
CPool ** pointRoutePool			= (CPool **)0xB744B0;
CPool ** patrolRoutePool		= (CPool **)0xB744B4;
CPool ** nodeRoutePool			= (CPool **)0xB744B8;
CPool ** taskAllocatorPool		= (CPool **)0xB744BC;
CPool ** pedIntelligencePool	= (CPool **)0xB744C0;
CPool ** pedAttractorPool		= (CPool **)0xB744C4;

CPool ** envMapPipeMatDataPool	= (CPool **)0xC02D28;
CPool ** envMapPipeAtmDataPool	= (CPool **)0xC02D2C;
CPool ** specMapPipeMatDataPool	= (CPool **)0xC02D30;

CPool ** stuntJumpPool			= (CPool **)0xA9A888;
BYTE * isStuntQumpAllowed		= (BYTE *)0xA9A890;

CPool ** vehicleStructPool		= (CPool **)0xB4E680;

BYTE * allocatePtrNodeSingle () {	// >> 552380 (2)	TODO: inline it
	return (*ptrNodeSinglePool)->allocate ();
}
void releasePtrNodeSingle (BYTE * ptr) {	// >> 552390 (3)	TODO: inline it
	return (*ptrNodeSinglePool)->release (ptr);
}


void allocatePools () {	// >> 550F10
	debug ("allocating pools...\n");
	*ptrNodeSinglePool		= new CPool (70000, 8);
	*ptrNodeDoublePool		= new CPool (3200, 12);
	*entryInfoNodePool		= new CPool (500, 20);
	*pedPool				= new CPool (140, 0x7C4);
	*vehiclePool			= new CPool (110, 0xA18);
	*buildingPool			= new CPool (13000, 0x38);
	*objectPool				= new CPool (350, 0x19C);
	*dummyPool				= new CPool (2500, 0x38);
	*colModelPool			= new CPool (10150, 48);
	*taskPool				= new CPool (500, 128);
	*eventPool				= new CPool (200, 0x44);
	*pointRoutePool			= new CPool (64, 0x64);
	*patrolRoutePool		= new CPool (32, 0x1A4);
	*nodeRoutePool			= new CPool (64, 36);
	*taskAllocatorPool		= new CPool (16, 32);
	*pedIntelligencePool	= new CPool (140, 0x294);
	*pedAttractorPool		= new CPool (64, 0xC4);

	/* TODO: после AllocateMapPipe
	*envMapPipeMatDataPool	= new CPool (4096, 12);
	*envMapPipeAtmDataPool	= new CPool (1024, 12);
	*specMapPipeMatDataPool = new CPool (4096, 8);
	*/

//	*txdPool				= new CPool (5000, 12);
	// allocateStuntJumpsPool
	*stuntJumpPool			= new CPool (256, 0x44);
	*isStuntQumpAllowed		= 1;
}

void shutdownPools () {	// >> 5519F0
	debug ("Shutdown pools...\n");
	if (*ptrNodeSinglePool)		delete *ptrNodeSinglePool;
	if (*ptrNodeDoublePool)		delete *ptrNodeDoublePool;
	if (*entryInfoNodePool)		delete *entryInfoNodePool;
	if (*pedPool)				delete *pedPool;
	if (*vehiclePool)			delete *vehiclePool;
	if (*buildingPool)			delete *buildingPool;
	if (*objectPool)			delete *objectPool;
	if (*dummyPool)				delete *dummyPool;
	if (*colModelPool)			delete *colModelPool;
	if (*taskPool)				delete *taskPool;
	if (*eventPool)				delete *eventPool;
	if (*pointRoutePool)		delete *pointRoutePool;
	if (*patrolRoutePool)		delete *patrolRoutePool;
	if (*nodeRoutePool)			delete *nodeRoutePool;
	if (*taskAllocatorPool)		delete *taskAllocatorPool;
	if (*pedIntelligencePool)	delete *pedIntelligencePool;
	if (*pedAttractorPool)		delete *pedAttractorPool;

	/* TODO: после AllocateMapPipe
	if (*envMapPipeMatDataPool)	delete *envMapPipeMatDataPool;
	if (*envMapPipeAtmDataPool) delete *envMapPipeAtmDataPool;
	if (*specMapPipeMatDataPool)delete *specMapPipeMatDataPool;
	*/

	// if (*txdPool)				delete *txdPool;	// TODO:

	// releaseStuntJumpsPool
	if (*stuntJumpPool)			delete *stuntJumpPool;
}


/*

void shutdownTxdPool () { if (*txdPool)	delete *txdPool; }

// TODO: Добавить в конструктор CTxdPool
void initTxdPool () {	
	*txdPool = new CPool (5000, 12);	// TODO: сделать нормально инициализацию
	for (int i = 0; i < 4; i++)
		defaultTxds[i] = (*txdPool)->indexOf ((BYTE *)new CTxdEntry ("*"));
	RwTextureSetFindCallBack (textureFindCB);
	RwTextureSetReadCallBack (textureReadCB);
}

void poolsInject () {
	injectFunction (0x552380, (DWORD)allocatePtrNodeSingle);
	injectFunction (0x552390, (DWORD)releasePtrNodeSingle);
	injectFunction (0x550F10, (DWORD)allocatePools);
	injectFunction (0x5519F0, (DWORD)shutdownPools);	

	*(BYTE *)0x49CA50 = 0xC3;	// remove allocateStuntJumpsPool
	*(BYTE *)0x49CBC0 = 0xC3;	// remove releaseStuntJumpsPool
	// *(BYTE *)0x732000 = 0xC3;	// remove releaseTxdPool
	injectFunction (0x732000, (DWORD)shutdownTxdPool);

	injectFunction (0x731F20, (DWORD)initTxdPool);

}*/