// ### Open SanAndreas ###
// injector function (all in one)
#include "stdafx.h"
#include <assert.h>
#include "ogMath.h"
#include "ogMemory.h"
#include "ogRW.h"
#include "ogTextures.h"
#include "ogModels.h"
#include "ogHud.h"
#include "ogInput.h"
#include "ogGameObjects.h"
#include "ogScript.h"
#include "gtaInterface.h"


void test () {
	// some tests
	// debug ("Atomic 253F2F3 plugin: %d\n", *(DWORD *)0x8D6080);
	// debug ("Frame visibility plugin: %d\n", *(DWORD *)0x8D6090);	
	// debug ("Geometry 2dfx plugin: %d\n", *(DWORD *)0xC3A1E0);
	assert (*(DWORD *)0x8D6090 == 196);
}

extern int APIENTRY ogWinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
void pad__processMouse () { pad->processMouse (); }

void __stdcall camera__setPosAndRotate (D3DVECTOR * pos, D3DVECTOR * rotation) { camera->setPositionAndRotation (pos, rotation); }
void __stdcall camera__attach (CEntity * target, short mode1, short mode2, int _aC) { camera->attach (target, mode1, mode2, _aC); }

// void (updateZScale)(CRwCamera *) = (void (__cdecl *)(CRwCamera *))0x7EE200;
void updateZScale (CRwCamera * cam) { cam->updateZShuftScale (); }

typedef void (CScriptThread::* threadMethod1)(int p1);

threadMethod1 m_gnp = &CScriptThread::getNumberParams;
//=============================================================================
bool attachDll () {
	// some testing
	assert (sizeof (CModelCars) == 0x308);
	assert (sizeof (CEngine) == 0x158);
	assert (sizeof (CAtomic) == 140);
	assert (sizeof (CClump) == 64);
	assert (sizeof (CLight) == 100);
	assert (sizeof (CRwStream) == 36);
	assert (sizeof (CTexDictionary) == 28);
	assert (sizeof (CFrame) == 200);
	assert (sizeof (CModelBase) == 32);

	assert (sizeof (CCam) == 0x238);
	assert (sizeof (CCamera) == 0xD78);
	assert (sizeof (CEntity) == 56);
	assert (sizeof (CPhysical) == 0x138);
	assert (sizeof (CPed) == 0x79C);
	assert (sizeof (CCopPed) == 0x7C4);
	assert (sizeof (CPlayerPed) == 0x7A4);
	assert (sizeof (CPlayerData) == 0xAC);
	assert (sizeof (CPlayer) == 0x190); 
	assert (sizeof (CGarage) == 0xD8);

	// script engine
	assert (sizeof (CScriptThread) == 0xE0);
	assert (sizeof (CTextDrawer) == 0x44);
	assert (sizeof (CTextSprite) == 0x3C);

	injectFunction (0x46A000, (DWORD)script_process);
	

	// ogMath
	injectFunction (0x40FDB0, (DWORD)dotProduct);
	injectFunction (0x59C730, (DWORD)crossProduct);	
	injectFunction (0x40FE30, (DWORD)vectorAdd);			
	injectFunction (0x40FE60, (DWORD)vectorSub);			

	// # bamemory
	injectFunction (0x801FD0, (DWORD)_rwMemoryOpen);
	injectFunction (0x8020F0, (DWORD)_rwMemoryClose);
	injectFunction (0x801F90, (DWORD)RwPurgeAllFreeLists);
	injectFunction (0x801E00, (DWORD)RwFreeListPurge);
	injectFunction (0x801E90, (DWORD)RwFreeListForAllUsed);
	injectFunction (0x801C30, (DWORD)_rwFreeListAllocReal);
	injectFunction (0x801D50, (DWORD)_rwFreeListFreeReal);
	injectFunction (0x8019B0, (DWORD)FreeListCreate);
	injectFunction (0x801B80, (DWORD)RwFreeListDestroy);

	// memory
	injectFunction (0x72F420, (DWORD)RwMalloc);			
	injectFunction (0x72F430, (DWORD)RwFree);			
	injectFunction (0x72F440, (DWORD)RwRealloc);
	injectFunction (0x72F460, (DWORD)RwCalloc);
	injectFunction (0x82119A, (DWORD)newWrapper);
	injectFunction (0x8214BD, (DWORD)deleteWrapper);

	// pools
	injectFunction (0x550F10, (DWORD)allocatePools);
	injectFunction (0x5519F0, (DWORD)shutdownPools);
	*(BYTE *)0x49CA50 = 0xC3;	// remove allocateStuntJumpsPool
	*(BYTE *)0x49CBC0 = 0xC3;	// remove releaseStuntJumpsPool
	
	injectFunction (0x731F20, (DWORD)initTxdPool);
	injectFunction (0x732000, (DWORD)releaseTxdPool);

	// CTextureManager - replacement of RwTextureModule
	injectFunction (0x7316D0, (DWORD)getDefaultTxd);
	injectFunction (0x7F34D0, (DWORD)RwTextureSetFindCallBack);
	injectFunction (0x7F34F0, (DWORD)RwTextureGetFindCallBack);
	injectFunction (0x7F3530, (DWORD)RwTextureSetMipmapping);
	injectFunction (0x7F3550, (DWORD)RwTextureGetMipmapping);
	injectFunction (0x7F3560, (DWORD)RwTextureSetAutoMipmapping);
	injectFunction (0x7F3580, (DWORD)RwTextureGetAutoMipmapping);
	injectFunction (0x7F3600, (DWORD)RwTexDictionaryCreate);
	injectFunction (0x7F36A0, (DWORD)RwTexDictionaryDestroy);
	injectFunction (0x7F37C0, (DWORD)RwTextureCreate);
	injectFunction (0x7F3820, (DWORD)RwTextureDestroy);
	injectFunction (0x7F3A70, (DWORD)RwTexDictionarySetCurrent);
	injectFunction (0x7F3A90, (DWORD)RwTexDictionaryGetCurrent);
	injectFunction (0x7F3AC0, (DWORD)RwReadTexture);
	injectFunction (0x7F3CD0, (DWORD)RwTextureRasterGenerateMipmaps);
	injectFunction (0x7F39F0, (DWORD)RwTexDictionaryFindNamedTexture);

	// streams
	injectFunction (0x7ECEF0, (DWORD)RwStreamOpen);
	injectFunction (0x7ECE20, (DWORD)RwStreamClose);
	injectFunction (0x7EC9D0, (DWORD)RwStreamRead);
	injectFunction (0x7ECB30, (DWORD)RwStreamWrite);
	injectFunction (0x7ECD00, (DWORD)RwStreamSkip);
	injectFunction (0x7EC810, (DWORD)_rwStreamInitialize);
	injectFunction (0x7ED0F0, (DWORD)_rwStreamReadChunkHeader);
	injectFunction (0x7ED540, (DWORD)_rwStreamReadData);	// RwStreamReadInt32
	injectFunction (0x7ED4F0, (DWORD)_rwStreamReadData);	// RwStreamReadReal
	injectFunction (0x7ED590, (DWORD)RwStreamReadChunkHeaderInfo);
	injectFunction (0x7ED2D0, (DWORD)RwStreamFindChunk);

	injectFunction (0x823521, (DWORD)fread);
	injectFunction (0x8232D8, (DWORD)fopen);
	injectFunction (0x823674, (DWORD)fwrite);
	injectFunction (0x82374F, (DWORD)fseek);
	injectFunction (0x823798, (DWORD)fgets);
	injectFunction (0x82318B, (DWORD)fclose);
	injectFunction (0x8262A2, (DWORD)feof);
	injectFunction (0x823E86, (DWORD)fflush);
	injectFunction (0x826261, (DWORD)ftell);

	// atomics
	injectFunction (0x749C50, (DWORD)RpAtomicCreate);
	injectFunction (0x749DC0, (DWORD)RpAtomicDestroy);
	injectFunction (0x7496A0, (DWORD)RpAtomicDestroy);	// ClumpTidyDestroyAtomic
	injectFunction (0x749E60, (DWORD)RpAtomicClone);

	// clumps
	injectFunction (0x74A290, (DWORD)RpClumpCreate);
	injectFunction (0x74A310, (DWORD)RpClumpDestroy);

	// camera
	injectFunction (0x7EE200, (DWORD)updateZScale);

	// frame
	injectFunction (0x7F0410, (DWORD)RwFrameCreate);
	injectFunction (0x7F05A0, (DWORD)RwFrameDestroy);
	injectFunction (0x7F0B00, (DWORD)RwFrameAddChild);

	// models
	injectFunction (0x41B350, (DWORD)collisionPlugin_setCurrentModel);			
	injectFunction (0x41B1D0, (DWORD)collisionPlugin_read);			
	injectFunction (0x4C5940, (DWORD)getModelIndexByName);

	injectFunction (0x44D2B0, (DWORD)test);	

	// game objects
	injectFunction (0x50BEC0, (DWORD)camera__setPosAndRotate);
	injectFunction (0x50C7C0, (DWORD)camera__attach);

	// config
	injectFunction (0x5B9030, (DWORD)readGameConfig);

	// main
	injectFunction (0x748710, (DWORD)ogWinMain);

	// input
	injectFunction (0x53F3C0, (DWORD)pad__processMouse);		

	// entities
	injectFunction (0x5719B0, (DWORD)initializeReferences);

	//	injectFunction (0x, (DWORD));
	return true;
}