summaryrefslogtreecommitdiff
path: root/src/koopatlas
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2012-09-27 04:40:34 +0200
committerTreeki <treeki@gmail.com>2012-09-27 04:40:34 +0200
commit411c5a8e210b5cbca330a5438e2406dbe1ffecab (patch)
treee3df3b98058dc979b759080504f52cd88e68d2b4 /src/koopatlas
parent014f3668eb47b1576bdc182b1db00417f9938cf1 (diff)
downloadkamek-411c5a8e210b5cbca330a5438e2406dbe1ffecab.tar.gz
kamek-411c5a8e210b5cbca330a5438e2406dbe1ffecab.zip
made world changes work, and HUD colourising and other fun things
Diffstat (limited to 'src/koopatlas')
-rw-r--r--src/koopatlas/hud.cpp158
-rw-r--r--src/koopatlas/hud.h21
-rw-r--r--src/koopatlas/mapdata.cpp2
-rw-r--r--src/koopatlas/pathmanager.cpp11
4 files changed, 177 insertions, 15 deletions
diff --git a/src/koopatlas/hud.cpp b/src/koopatlas/hud.cpp
index 4f4ce2f..84329bf 100644
--- a/src/koopatlas/hud.cpp
+++ b/src/koopatlas/hud.cpp
@@ -1,5 +1,146 @@
#include "koopatlas/hud.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 + (n1 - 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;
dWMHud_c *dWMHud_c::build() {
@@ -63,13 +204,13 @@ int dWMHud_c::onCreate() {
layout.getPanes(paneNames, &N_IconPosXP_00[0], 4);
static const char *pictureNames[] = {
- "Header_Centre", "Header_Right",
+ "Header_Centre", "Header_Right", "Footer",
"NormalExitFlag", "SecretExitFlag",
"StarCoinOn0", "StarCoinOn1", "StarCoinOn2",
"P_marioFace_00", "P_luigiFace_00",
"P_BkinoFace_00", "P_YkinoFace_00"
};
- layout.getPictures(pictureNames, &Header_Centre, 11);
+ layout.getPictures(pictureNames, &Header_Centre, 12);
static const char *textBoxNames[] = {
"LevelName", "LevelNameS",
@@ -81,6 +222,10 @@ int dWMHud_c::onCreate() {
};
layout.getTextBoxes(textBoxNames, &LevelName, 11);
+ headerCol.setTexMap(Header_Right->material->texMaps);
+ headerCol.applyAlso(Header_Centre->material->texMaps);
+ footerCol.setTexMap(Footer->material->texMaps);
+
layoutLoaded = true;
willShowHeader = false;
@@ -228,6 +373,9 @@ void dWMHud_c::loadHeaderInfo() {
totalWidth = 270.0f;
Header_Centre->size.x = totalWidth;
Header_Right->trans.x = totalWidth;
+
+ SaveBlock *save = GetSaveFile()->GetBlock(-1);
+ headerCol.colourise(save->hudHintH, save->hudHintS, save->hudHintL);
}
@@ -246,8 +394,10 @@ void dWMHud_c::loadFooterInfo() {
WorldName->SetString(convertedWorldName);
WorldNameS->SetString(convertedWorldName);
- WorldName->colour1 = save->hudTextColour[0];
- WorldName->colour2 = save->hudTextColour[1];
+ WorldName->colour1 = save->hudTextColours[0];
+ WorldName->colour2 = save->hudTextColours[1];
+
+ footerCol.colourise(save->hudHintH, save->hudHintS, save->hudHintL);
}
diff --git a/src/koopatlas/hud.h b/src/koopatlas/hud.h
index deac84f..c0079af 100644
--- a/src/koopatlas/hud.h
+++ b/src/koopatlas/hud.h
@@ -3,6 +3,23 @@
#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;
+};
+
class dWMHud_c : public dBase_c {
public:
dWMHud_c();
@@ -39,12 +56,14 @@ class dWMHud_c : public dBase_c {
void loadFooterInfo();
bool willShowFooter;
+ dTexMapColouriser_c headerCol, footerCol;
+
nw4r::lyt::Pane
*N_IconPosXP_00[4];
nw4r::lyt::Picture
- *Header_Centre, *Header_Right,
+ *Header_Centre, *Header_Right, *Footer,
*NormalExitFlag, *SecretExitFlag,
*StarCoinOn[3],
*P_marioFace_00, *P_luigiFace_00,
diff --git a/src/koopatlas/mapdata.cpp b/src/koopatlas/mapdata.cpp
index 29c6a23..d4f9d0c 100644
--- a/src/koopatlas/mapdata.cpp
+++ b/src/koopatlas/mapdata.cpp
@@ -286,7 +286,7 @@ void dKPMapData_c::fixup() {
}
-const dKPWorldDef_s *dKPMapData_c::findWorldDef(int id) {
+const dKPWorldDef_s *dKPMapData_c::findWorldDef(int id) const {
for (int i = 0; i < data->worldCount; i++) {
if (data->worlds[i].key == id)
return &data->worlds[i];
diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp
index 2401e04..896707a 100644
--- a/src/koopatlas/pathmanager.cpp
+++ b/src/koopatlas/pathmanager.cpp
@@ -566,7 +566,7 @@ void dWMPathManager_c::moveThroughPath() {
isJumping = false;
timer = 0.0;
- SpammyReport("reached path end (%p)\n", to);
+ SpammyReport("reached path end (%p) with type %d\n", to, to->type);
bool reallyStop = false;
@@ -595,7 +595,7 @@ void dWMPathManager_c::moveThroughPath() {
SaveBlock *save = GetSaveFile()->GetBlock(-1);
OSReport("Activating world change %d\n", to->worldID);
- dKPWorldDef_s *world = dScKoopatlas_c::instance->mapData.findWorldDef(to->worldID);
+ const dKPWorldDef_s *world = dScKoopatlas_c::instance->mapData.findWorldDef(to->worldID);
if (world) {
OSReport("Found!\n");
strncpy(save->newerWorldName, world->name, 36);
@@ -653,13 +653,6 @@ void dWMPathManager_c::moveThroughPath() {
save->current_path_node = pathLayer->findNodeID(to);
if (!calledEnteredNode)
dWMHud_c::instance->enteredNode();
-
- if (to->type == dKPNode_s::LEVEL) {
- NWRWorld nWorld = NewerWorldForLevelID(to->levelNumber[0], to->levelNumber[1]);
- if (nWorld != UNKNOWN_WORLD) {
- save->currentNewerWorld = (u8)nWorld;
- }
- }
} else {
startMovementTo(to->getOppositeAvailableExitTo(currentPath));
SpammyReport("passthrough node, continuing to next path\n");