diff options
Diffstat (limited to '')
| -rw-r--r-- | include/g3dhax.h | 4 | ||||
| -rwxr-xr-x | include/game.h | 5 | ||||
| -rw-r--r-- | kamek_pal.x | 4 | ||||
| -rw-r--r-- | koopatlas.yaml | 1 | ||||
| -rw-r--r-- | src/koopatlas/core.cpp | 2 | ||||
| -rw-r--r-- | src/koopatlas/hud.cpp | 139 | ||||
| -rw-r--r-- | src/koopatlas/hud.h | 18 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.cpp | 4 | ||||
| -rw-r--r-- | src/koopatlas/shop.cpp | 117 | ||||
| -rw-r--r-- | src/koopatlas/shop.h | 11 | ||||
| -rw-r--r-- | src/texmapcolouriser.cpp | 142 | ||||
| -rw-r--r-- | src/texmapcolouriser.h | 22 | 
12 files changed, 292 insertions, 177 deletions
| diff --git a/include/g3dhax.h b/include/g3dhax.h index 8a2063a..85dc922 100644 --- a/include/g3dhax.h +++ b/include/g3dhax.h @@ -322,7 +322,7 @@ namespace m3d {  			bool setup(nw4r::g3d::ResMdl modelRes, nw4r::g3d::ResAnmChr anmRes,  					mAllocator_c *allocator, u32 *sizeOutPtr); -			void bind(/*b*/mdl_c *model, nw4r::g3d::ResAnmChr anmRes, int unk); +			void bind(/*b*/mdl_c *model, nw4r::g3d::ResAnmChr anmRes, bool playsOnce);  	};  	class anmVis_c : public fanm_c { @@ -333,7 +333,7 @@ namespace m3d {  			bool setup(nw4r::g3d::ResMdl modelRes, nw4r::g3d::ResAnmVis anmRes,  					mAllocator_c *allocator, u32 *sizeOutPtr); -			void bind(/*b*/mdl_c *model, nw4r::g3d::ResAnmVis anmRes, int unk); +			void bind(/*b*/mdl_c *model, nw4r::g3d::ResAnmVis anmRes, bool playsOnce);  	};  	class anmClr_c : public fanm_c { diff --git a/include/game.h b/include/game.h index 48c7f65..c4a9238 100755 --- a/include/game.h +++ b/include/game.h @@ -132,6 +132,11 @@ class GameMgr {  		u8 _AFC, _AFD, _AFE[88];
  		u8 _B56[4];
  		u8 _B5A, _B5B;
 +
 +		void giveOneStockPowerup(int type); // 800BB330
 +		void takeOneStockPowerup(int type); // 800BB380
 +		int getStockPowerupCount(int type); // 800BB3D0
 +		void resetStockPowerupCount(int type); // 800BB410
  };
  extern GameMgr *GameMgrP;
 diff --git a/kamek_pal.x b/kamek_pal.x index 7cfd502..0332692 100644 --- a/kamek_pal.x +++ b/kamek_pal.x @@ -1343,7 +1343,7 @@ SECTIONS {  	__dt__Q23m3d8anmChr_cFv = 0x800260c0;  	vf0C__Q23m3d8anmChr_cFv = 0x8002a210;  	setup__Q23m3d8anmChr_cFQ34nw4r3g3d6ResMdlQ34nw4r3g3d9ResAnmChrP12mAllocator_cPUi = 0x80165210; -	bind__Q23m3d8anmChr_cFPQ23m3d5mdl_cQ34nw4r3g3d9ResAnmChri = 0x80165330; +	bind__Q23m3d8anmChr_cFPQ23m3d5mdl_cQ34nw4r3g3d9ResAnmChrb = 0x80165330;  	internalBind__Q23m3d8anmChr_cFv = 0x801653c0;  	/* m3d::anmVis_c */ @@ -1351,7 +1351,7 @@ SECTIONS {  	__dt__Q23m3d8anmVis_cFv = 0x809b2090;  	vf0C__Q23m3d8anmVis_cFv = 0x809b3c20;  	setup__Q23m3d8anmVis_cFQ34nw4r3g3d6ResMdlQ34nw4r3g3d9ResAnmVisP12mAllocator_cPUi = 0x80167d80; -	bind__Q23m3d8anmVis_cFPQ23m3d5mdl_cQ34nw4r3g3d9ResAnmVisi = 0x80167ea0; +	bind__Q23m3d8anmVis_cFPQ23m3d5mdl_cQ34nw4r3g3d9ResAnmVisb = 0x80167ea0;  	internalBind__Q23m3d8anmVis_cFv = 0x80167f90;  	/* m3d::anmClr_c */ diff --git a/koopatlas.yaml b/koopatlas.yaml index eea87e6..3556996 100644 --- a/koopatlas.yaml +++ b/koopatlas.yaml @@ -13,6 +13,7 @@ source_files:    - ../src/koopatlas/pathmanager.cpp    - ../src/koopatlas/shop.cpp    - ../src/koopatlas/starcoin.cpp +  - ../src/texmapcolouriser.cpp  hooks:    - name: BuildWorldMap # WORLD_MAP diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp index 6fb030a..249861f 100644 --- a/src/koopatlas/core.cpp +++ b/src/koopatlas/core.cpp @@ -265,7 +265,7 @@ bool WMInit_SetupExtra(void *ptr) {  	// it is created in dScKoopatlas_c::onCreate  	SpammyReport("creating SHOP\n"); -	wm->shop = (dWMShop_c*)CreateParentedObject(WM_SHOP, wm, 0, 0); +	wm->shop = (dWMShop_c*)CreateParentedObject(WM_SHOP, wm, 0, 2);  	SpammyReport("creating Star Coin Menu\n");  	wm->coins = (dWMStarCoin_c*)CreateParentedObject(WM_STARCOIN, wm, 0, 0); diff --git a/src/koopatlas/hud.cpp b/src/koopatlas/hud.cpp index 2479133..ab093ef 100644 --- a/src/koopatlas/hud.cpp +++ b/src/koopatlas/hud.cpp @@ -2,145 +2,6 @@  #include <newer.h> -dTexMapColouriser_c::dTexMapColouriser_c() { -	texmap = 0; -	original = 0; -	mine = 0; -} - -void *EGG__Heap__alloc(unsigned long size, int unk, void *heap); -void EGG__Heap__free(void *ptr, void *heap); - -dTexMapColouriser_c::~dTexMapColouriser_c() { -	resetAndClear(); -} - -void dTexMapColouriser_c::resetAndClear() { -	texmap = 0; -	if (mine) { -		EGG__Heap__free(mine, 0); -		mine = 0; -	} -} - -void dTexMapColouriser_c::setTexMap(nw4r::lyt::TexMap *tm) { -	OSReport("Colourising TexMap: %p (w:%d h:%d)\n", tm, tm->width, tm->height); -	if (texmap) -		resetAndClear(); - -	if (tm->mBits.textureFormat != GX_TF_IA8) { -		OSReport("Warning: Trying to colourise image whose format is %d not GX_TF_IA8\n", tm->mBits.textureFormat); -	} - -	texmap = tm; -	original = (u16*)tm->image; -	mine = (u16*)EGG__Heap__alloc(tm->width * tm->height * 4, 0x20, mHeap::gameHeaps[2]); -	tm->image = mine; -	tm->mBits.textureFormat = GX_TF_RGBA8; -} - -void dTexMapColouriser_c::applyAlso(nw4r::lyt::TexMap *tm) { -	if (!texmap) { -		setTexMap(tm); -	} else { -		tm->image = mine; -		tm->mBits.textureFormat = GX_TF_RGBA8; -	} -} - -inline static float hslValue(float n1, float n2, float hue) { -	if (hue > 6.0f) -		hue -= 6.0f; -	else if (hue < 0.0f) -		hue += 6.0f; - -	if (hue < 1.0f) -		return n1 + (n2 - n1) * hue; -	else if (hue < 3.0f) -		return n2; -	else if (hue < 4.0f) -		return n1 + (n2 - n1) * (4.0f - hue); -	else -		return n1; -} - -void dTexMapColouriser_c::colourise(int h, int s, int l) { -	if (!mine) -		return; - -	int width = texmap->width, height = texmap->height; -	int texelW = width / 4, texelH = height / 4; - -	u16 *source = original, *dest = mine; - -	float hueParam = h / 360.0f; -	float satParam = s / 100.0f; -	float lumParam = l / 100.0f; - -	for (int texelY = 0; texelY < texelH; texelY++) { -		for (int texelX = 0; texelX < texelW; texelX++) { -			for (int y = 0; y < 4; y++) { -				for (int x = 0; x < 4; x++) { -					u8 intensity = *source & 0xFF; -					u8 alpha = *source >> 8; - -					u8 r, g, b; - -					// This is a hack -					if (alpha < 250) { -						r = g = b = intensity; -					} else { -						// converting from GIMP's colourise code... -						// h and s are always the same -						// l is the only thing we need to touch: -						// we get the luminance from the source pixel -						// (which, conveniently, is the intensity) -						// manipulate it using the passed l and then -						// convert the whole thing to RGB - -						float lum = intensity / 255.0f; - -						// manipulate it -						if (l > 0) { -							lum = lum * (1.0f - lumParam); -							lum += (1.0f - (1.0f - lumParam)); -						} else if (l < 0) { -							lum = lum * (lumParam + 1.0f); -						} - -						// make it RGB - -						if (s == 0) { -							r = g = b = lum*255.0f; -						} else { -							float m1, m2; -							if (lum <= 0.5f) -								m2 = lum * (1.0f + satParam); -							else -								m2 = lum + satParam - lum * satParam; - -							m1 = 2.0f * lum - m2; - -							r = hslValue(m1, m2, hueParam * 6.0f + 2.0) * 255.0f; -							g = hslValue(m1, m2, hueParam * 6.0f) * 255.0f; -							b = hslValue(m1, m2, hueParam * 6.0f - 2.0) * 255.0f; -						} -					} - -					// now write it -					dest[0] = (alpha<<8)|r; -					dest[16] = (g<<8)|b; - -					source++; -					dest++; -				} -			} - -			dest += 16; -		} -	} -} -  dWMHud_c *dWMHud_c::instance = 0; diff --git a/src/koopatlas/hud.h b/src/koopatlas/hud.h index ee64133..32a09be 100644 --- a/src/koopatlas/hud.h +++ b/src/koopatlas/hud.h @@ -2,23 +2,7 @@  #define __KOOPATLAS_HUD_H  #include "koopatlas/core.h" - -// Colourises an IA8 texture -class dTexMapColouriser_c { -	public: -		dTexMapColouriser_c(); -		~dTexMapColouriser_c(); - -		void resetAndClear(); -		void setTexMap(nw4r::lyt::TexMap *tm); -		void applyAlso(nw4r::lyt::TexMap *tm); -		void colourise(int h, int s, int l); - -	private: -		nw4r::lyt::TexMap *texmap; -		u16 *original; -		u16 *mine; -}; +#include "texmapcolouriser.h"  class dWMHud_c : public dBase_c {  	public: diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index fa2a862..5d301df 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -657,10 +657,10 @@ void dWMPathManager_c::moveThroughPath() {  			OSReport("Activating world change %d\n", to->worldID);  			const dKPWorldDef_s *world = dScKoopatlas_c::instance->mapData.findWorldDef(to->worldID);  			if (world) { -				bool visiblyChange = false; +				bool visiblyChange = true;  				if (strncmp(save->newerWorldName, world->name, 32) == 0) {  					OSReport("Already here, but setting BGM track\n"); -					visiblyChange = true; +					visiblyChange = false;  				}  				OSReport("Found!\n"); diff --git a/src/koopatlas/shop.cpp b/src/koopatlas/shop.cpp index 9da5fc0..b42c58a 100644 --- a/src/koopatlas/shop.cpp +++ b/src/koopatlas/shop.cpp @@ -15,13 +15,14 @@ void dWMShop_c::ShopModel_c::setupItem(float x, float y, ItemTypes type) {  		{ "I_propeller", 	"g3d/I_propeller.brres", 		"I_propeller_model", 	"wait2" },  		{ "I_kinoko_bundle","g3d/I_mini_kinoko.brres", 		"I_mini_kinoko", 		"wait2" },  		{ "I_star", 		"g3d/I_star.brres", 			"I_star", 				"wait2" }, -		{ "I_hammer", 		"g3d/I_hammer.brres", 			"I_hammer", 			"wait2" }, +		{ "I_hammer", 		"g3d/I_fireflower.brres",		"I_fireflower",			"wait2" },  		{ "I_kinoko_bundle","g3d/I_life_kinoko.brres", 		"I_life_kinoko", 		"wait2" },  		{ "obj_coin", 		"g3d/obj_coin.brres", 			"obj_coin", 			"wait2" }  	};  	this->x = x;  	this->y = y; +	scaleFactor = 2.3f;  	int id = (int)type; @@ -29,8 +30,14 @@ void dWMShop_c::ShopModel_c::setupItem(float x, float y, ItemTypes type) {  	res.data = getResource(Produce[id][0], Produce[id][1]);  	nw4r::g3d::ResMdl mdlRes = res.GetResMdl(Produce[id][2]); -	model.setup(mdlRes, &allocator, ANM_VTX, 1, 0); -	SetupTextures_Item(&model, 1); +	model.setup(mdlRes, &allocator, 0x224, 1, 0); + +	if (type == COINS) { +		SetupTextures_MapObj(&model, 1); +		this->y += 20.0f; +		scaleFactor = 2.7f; +	} else +		SetupTextures_Item(&model, 1);  	nw4r::g3d::ResAnmChr anmChr = res.GetResAnmChr(Produce[id][3]);  	animation.setup(mdlRes, anmChr, &allocator, 0); @@ -45,12 +52,14 @@ void dWMShop_c::ShopModel_c::setupLakitu(int id) {  		"g3d/ghost.brres", "g3d/space.brres", "g3d/koopa.brres", "g3d/sewer.brres", "g3d/goldwood.brres"   	}; +	scaleFactor = 1.0f; +  	allocator.link(-1, GameHeaps[0], 0, 0x20);  	res.data = getResource("lakitu", models[id]);  	nw4r::g3d::ResMdl mdlRes = res.GetResMdl("lakitu"); -	model.setup(mdlRes, &allocator, ANM_VTX, 1, 0); -	SetupTextures_Item(&model, 1); +	model.setup(mdlRes, &allocator, 0x224, 1, 0); +	SetupTextures_Enemy(&model, 1);  	nw4r::g3d::ResAnmChr anmChr = res.GetResAnmChr("idle");  	animation.setup(mdlRes, anmChr, &allocator, 0); @@ -62,7 +71,7 @@ void dWMShop_c::ShopModel_c::setupLakitu(int id) {  void dWMShop_c::ShopModel_c::playAnim(const char *name, float rate) {  	nw4r::g3d::ResAnmChr anmChr = res.GetResAnmChr(name); -	animation.bind(&model, anmChr, 1); +	animation.bind(&model, anmChr, 0);  	model.bindAnim(&animation, 0.0f);  	animation.setUpdateRate(rate);  } @@ -73,12 +82,12 @@ void dWMShop_c::ShopModel_c::execute() {  void dWMShop_c::ShopModel_c::draw() {  	mMtx mtx; -	Vec pos = {250.0f, 170.0f, 3000.0f}; -	Vec scale = {1.0f, 1.0f, 1.0f}; -	mtx.translation(pos.x, pos.y, pos.z); - +	mtx.translation(x, y, 1000.0f);  	model.setDrawMatrix(mtx); + +	Vec scale = {scaleFactor, scaleFactor, scaleFactor};  	model.setScale(&scale); +  	model.calcWorld(false);  	model.scheduleForDrawing();  } @@ -111,7 +120,6 @@ int dWMShop_c::onCreate() {  		layout.build("shop.brlyt"); -		layout.layout.rootPane->trans.x = -112.0f;  		if (IsWideScreen()) {  			layout.layout.rootPane->scale.x = 0.735f;  		} else { @@ -154,6 +162,36 @@ int dWMShop_c::onCreate() {  		};  		layout.getTextBoxes(tbNames, &Title, 6); +		// Warning: weird code coming up +		const char *crap = "000102031\0" "2\0"; +		char name[12]; +		for (int i = 0; i < 6; i++) { +			strcpy(name, "BtnLeftXX"); +			name[7] = crap[i*2]; +			name[8] = crap[i*2+1]; +			BtnLeft[i] = layout.findPictureByName(name); + +			strcpy(name, "BtnMidXX"); +			name[6] = crap[i*2]; +			name[7] = crap[i*2+1]; +			BtnMid[i] = layout.findPictureByName(name); + +			strcpy(name, "BtnRightXX"); +			name[8] = crap[i*2]; +			name[9] = crap[i*2+1]; +			BtnRight[i] = layout.findPictureByName(name); +		} + +		leftCol.setTexMap(BtnLeft[0]->material->texMaps); +		midCol.setTexMap(BtnMid[0]->material->texMaps); +		rightCol.setTexMap(BtnRight[0]->material->texMaps); + +		for (int i = 1; i < 6; i++) { +			leftCol.applyAlso(BtnLeft[i]->material->texMaps); +			midCol.applyAlso(BtnMid[i]->material->texMaps); +			rightCol.applyAlso(BtnRight[i]->material->texMaps); +		} +  		layoutLoaded = true;  	} @@ -226,6 +264,7 @@ void dWMShop_c::beginState_ShowWait() {  	layout.enableNonLoopAnim(SHOW_ALL);  	visible = true; +	loadInfo();  	loadModels();  }  void dWMShop_c::executeState_ShowWait() { @@ -301,12 +340,14 @@ void dWMShop_c::endState_Wait() { }  void dWMShop_c::beginState_HideWait() {  	MapSoundPlayer(SoundRelatedClass, SE_SYS_DIALOGUE_OUT_AUTO, 1);  	layout.enableNonLoopAnim(HIDE_ALL); +	layout.enableNonLoopAnim(DEACTIVATE_BUTTON+selected);  }  void dWMShop_c::executeState_HideWait() {  	if (!layout.isAnimOn(HIDE_ALL))  		state.setState(&StateID_Hidden);  }  void dWMShop_c::endState_HideWait() { +	deleteModels();  	visible = false;  } @@ -384,10 +425,29 @@ const dWMShop_c::ItemTypes dWMShop_c::Inventory[10][12] = {  void dWMShop_c::loadModels() {  	lakituModel = new ShopModel_c;  	lakituModel->setupLakitu(shopKind); +	lakituModel->x = 240.0f; +	lakituModel->y = 220.0f; + +	static const float itemPos[ITEM_COUNT][2] = { +		{357.0f, 276.0f}, +		{450.0f, 276.0f}, +		{543.0f, 276.0f}, +		{636.0f, 276.0f}, + +		{380.0f, 190.0f}, +		{462.0f, 190.0f}, +		{544.0f, 190.0f}, + +		{363.0f, 104.0f}, +		{413.0f, 104.0f}, +		{463.0f, 104.0f}, +		{513.0f, 104.0f}, +		{563.0f, 104.0f}, +	};  	itemModels = new ShopModel_c[ITEM_COUNT];  	for (int i = 0; i < ITEM_COUNT; i++) -		itemModels[i].setupItem(0.0f, 0.0f, Inventory[shopKind][i]); +		itemModels[i].setupItem(itemPos[i][0], itemPos[i][1], Inventory[shopKind][i]);  }  void dWMShop_c::deleteModels() {  	if (lakituModel) @@ -400,6 +460,39 @@ void dWMShop_c::deleteModels() {  } +void dWMShop_c::loadInfo() { +	SaveBlock *save = GetSaveFile()->GetBlock(-1); + +	leftCol.colourise(save->hudHintH, save->hudHintS, save->hudHintL); +	midCol.colourise(save->hudHintH, save->hudHintS, save->hudHintL); +	rightCol.colourise(save->hudHintH, save->hudHintS, save->hudHintL); + +	// find out the shop name +	dLevelInfo_c::entry_s *shopNameEntry = +		dLevelInfo_c::s_info.searchBySlot(shopKind, 98); + +	wchar_t shopName[100]; +	// TODO: refactor this a bit +	const char *sourceName = dLevelInfo_c::s_info.getNameForLevel(shopNameEntry); +	int charCount = 0; +	 +	while (*sourceName != 0 && charCount < 99) { +		shopName[charCount] = *sourceName; +		sourceName++; +		charCount++; +	} +	shopName[charCount] = 0; + +	Title->SetString(shopName); +	TitleShadow->SetString(shopName); + +	// load the coin count +	int scCount = getStarCoinCount(); +	WriteNumberToTextBox(&scCount, CoinCount, false); +	WriteNumberToTextBox(&scCount, CoinCountShadow, false); +} + +  void dWMShop_c::buyItem(int item) {  	static int itemDefs[6][3] = {  		// Cost, Start Index, Count diff --git a/src/koopatlas/shop.h b/src/koopatlas/shop.h index 719a087..304154a 100644 --- a/src/koopatlas/shop.h +++ b/src/koopatlas/shop.h @@ -2,8 +2,9 @@  #define __KOOPATLAS_SHOP_H  #include "koopatlas/core.h" +#include "texmapcolouriser.h" -class dWMShop_c : public dBase_c { +class dWMShop_c : public dActor_c {  	public:  		static dWMShop_c *build();  		static dWMShop_c *instance; @@ -56,6 +57,11 @@ class dWMShop_c : public dBase_c {  			*CoinCount, *CoinCountShadow,  			*BackText, *BuyText; +		nw4r::lyt::Picture +			*BtnLeft[6], *BtnMid[6], *BtnRight[6]; + +		dTexMapColouriser_c leftCol, midCol, rightCol; +  		class ShopModel_c {  			public:  				mHeapAllocator_c allocator; @@ -64,7 +70,7 @@ class dWMShop_c : public dBase_c {  				m3d::mdl_c model;  				m3d::anmChr_c animation; -				float x, y; +				float x, y, scaleFactor;  				void setupItem(float x, float y, ItemTypes type);  				void setupLakitu(int id); @@ -78,6 +84,7 @@ class dWMShop_c : public dBase_c {  		void show(int shopNumber); +		void loadInfo();  		void loadModels();  		void deleteModels(); diff --git a/src/texmapcolouriser.cpp b/src/texmapcolouriser.cpp new file mode 100644 index 0000000..1aa2d7c --- /dev/null +++ b/src/texmapcolouriser.cpp @@ -0,0 +1,142 @@ +#include "texmapcolouriser.h" + +dTexMapColouriser_c::dTexMapColouriser_c() { +	texmap = 0; +	original = 0; +	mine = 0; +} + +void *EGG__Heap__alloc(unsigned long size, int unk, void *heap); +void EGG__Heap__free(void *ptr, void *heap); + +dTexMapColouriser_c::~dTexMapColouriser_c() { +	resetAndClear(); +} + +void dTexMapColouriser_c::resetAndClear() { +	texmap = 0; +	if (mine) { +		EGG__Heap__free(mine, 0); +		mine = 0; +	} +} + +void dTexMapColouriser_c::setTexMap(nw4r::lyt::TexMap *tm) { +	OSReport("Colourising TexMap: %p (w:%d h:%d)\n", tm, tm->width, tm->height); +	if (texmap) +		resetAndClear(); + +	if (tm->mBits.textureFormat != GX_TF_IA8) { +		OSReport("Warning: Trying to colourise image whose format is %d not GX_TF_IA8\n", tm->mBits.textureFormat); +	} + +	texmap = tm; +	original = (u16*)tm->image; +	mine = (u16*)EGG__Heap__alloc(tm->width * tm->height * 4, 0x20, mHeap::gameHeaps[2]); +	tm->image = mine; +	tm->mBits.textureFormat = GX_TF_RGBA8; +} + +void dTexMapColouriser_c::applyAlso(nw4r::lyt::TexMap *tm) { +	if (!texmap) { +		setTexMap(tm); +	} else { +		tm->image = mine; +		tm->mBits.textureFormat = GX_TF_RGBA8; +	} +} + +inline static float hslValue(float n1, float n2, float hue) { +	if (hue > 6.0f) +		hue -= 6.0f; +	else if (hue < 0.0f) +		hue += 6.0f; + +	if (hue < 1.0f) +		return n1 + (n2 - n1) * hue; +	else if (hue < 3.0f) +		return n2; +	else if (hue < 4.0f) +		return n1 + (n2 - n1) * (4.0f - hue); +	else +		return n1; +} + +void dTexMapColouriser_c::colourise(int h, int s, int l) { +	if (!mine) +		return; + +	int width = texmap->width, height = texmap->height; +	int texelW = width / 4, texelH = height / 4; + +	u16 *source = original, *dest = mine; + +	float hueParam = h / 360.0f; +	float satParam = s / 100.0f; +	float lumParam = l / 100.0f; + +	for (int texelY = 0; texelY < texelH; texelY++) { +		for (int texelX = 0; texelX < texelW; texelX++) { +			for (int y = 0; y < 4; y++) { +				for (int x = 0; x < 4; x++) { +					u8 intensity = *source & 0xFF; +					u8 alpha = *source >> 8; + +					u8 r, g, b; + +					// This is a hack +					if (alpha < 250) { +						r = g = b = intensity; +					} else { +						// converting from GIMP's colourise code... +						// h and s are always the same +						// l is the only thing we need to touch: +						// we get the luminance from the source pixel +						// (which, conveniently, is the intensity) +						// manipulate it using the passed l and then +						// convert the whole thing to RGB + +						float lum = intensity / 255.0f; + +						// manipulate it +						if (l > 0) { +							lum = lum * (1.0f - lumParam); +							lum += (1.0f - (1.0f - lumParam)); +						} else if (l < 0) { +							lum = lum * (lumParam + 1.0f); +						} + +						// make it RGB + +						if (s == 0) { +							r = g = b = lum*255.0f; +						} else { +							float m1, m2; +							if (lum <= 0.5f) +								m2 = lum * (1.0f + satParam); +							else +								m2 = lum + satParam - lum * satParam; + +							m1 = 2.0f * lum - m2; + +							r = hslValue(m1, m2, hueParam * 6.0f + 2.0) * 255.0f; +							g = hslValue(m1, m2, hueParam * 6.0f) * 255.0f; +							b = hslValue(m1, m2, hueParam * 6.0f - 2.0) * 255.0f; +						} +					} + +					// now write it +					dest[0] = (alpha<<8)|r; +					dest[16] = (g<<8)|b; + +					source++; +					dest++; +				} +			} + +			dest += 16; +		} +	} +} + + diff --git a/src/texmapcolouriser.h b/src/texmapcolouriser.h new file mode 100644 index 0000000..22d5d25 --- /dev/null +++ b/src/texmapcolouriser.h @@ -0,0 +1,22 @@ +#ifndef TEXMAPCOLOURISER_H +#define TEXMAPCOLOURISER_H  +#include <game.h> + +// Colourises an IA8 texture +class dTexMapColouriser_c { +	public: +		dTexMapColouriser_c(); +		~dTexMapColouriser_c(); + +		void resetAndClear(); +		void setTexMap(nw4r::lyt::TexMap *tm); +		void applyAlso(nw4r::lyt::TexMap *tm); +		void colourise(int h, int s, int l); + +	private: +		nw4r::lyt::TexMap *texmap; +		u16 *original; +		u16 *mine; +}; + +#endif /* TEXMAPCOLOURISER_H */ | 
