diff options
author | Treeki <treeki@gmail.com> | 2012-10-25 04:59:11 +0200 |
---|---|---|
committer | Treeki <treeki@gmail.com> | 2012-10-25 04:59:11 +0200 |
commit | 0bee9e3ae3bd5a9f4a9f0ea8a4d04955a90798fa (patch) | |
tree | 999ea89b9eb357fbd4a0b7d8acd6c71f2a82c8f6 | |
parent | 47795a5f0eee896df557e4e3481068e510fe51fb (diff) | |
download | kamek-0bee9e3ae3bd5a9f4a9f0ea8a4d04955a90798fa.tar.gz kamek-0bee9e3ae3bd5a9f4a9f0ea8a4d04955a90798fa.zip |
refactoring, API fixes and shop mostly finished
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 */ |