summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xinclude/game.h36
-rw-r--r--include/newer.h26
-rw-r--r--src/fileselect.S59
-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
-rw-r--r--src/newer.cpp76
8 files changed, 250 insertions, 139 deletions
diff --git a/include/game.h b/include/game.h
index 41b925f..32b3a1d 100755
--- a/include/game.h
+++ b/include/game.h
@@ -560,7 +560,13 @@ namespace ut {
LinkListNode initialNode;
};
- class Color : public GXColor { };
+ class Color : public GXColor {
+ public:
+ GXColor& operator=(const GXColor &other) {
+ *((u32*)this) = *((u32*)&other);
+ return *this;
+ }
+ };
class Rect {
public:
@@ -651,9 +657,35 @@ namespace lyt {
};
+ class TexMap {
+ public:
+ void *image, *palette;
+ u16 width, height;
+ f32 minLOD, magLOD;
+ u16 lodBias, palEntryNum;
+ struct
+ {
+ u32 textureFormat: 4;
+ u32 mipmap: 1;
+ u32 wrapS: 2;
+ u32 wrapT: 2;
+ u32 minFilter: 3;
+ u32 magFilter: 1;
+ u32 biasClampEnable: 1;
+ u32 edgeLODEnable: 1;
+ u32 anisotropy: 2;
+ u32 paletteFormat: 2;
+ } mBits;
+ };
+
class Material {
public:
- // ...
+ virtual ~Material();
+
+ // cheating a bit here
+ u8 _[0x3C];
+ // this is actually a pointer to more stuff, not just texmaps
+ TexMap *texMaps;
};
class Pane {
diff --git a/include/newer.h b/include/newer.h
index d98f290..cf21cbb 100644
--- a/include/newer.h
+++ b/include/newer.h
@@ -1,32 +1,6 @@
#ifndef NEWER_H
#define NEWER_H
-enum NWRWorld {
- ISLAND = 0, YOSHI_ISLAND = 0,
- DESERT = 1, RUBBLE_RUINS = 1,
- SEWER = 2, SOGGY_SEWERS = 2,
- MOUNTAIN = 3, MUSHROOM_PEAKS = 3,
- SAKURA = 4, SAKURA_VILLAGE = 4,
- FREEZEFLAME = 5, FREEZEFLAME_GLACIER = 5,
- VOLCANO = 6, FREEZEFLAME_VOLCANO = 6,
- PUMPKIN = 7, PUMPKIN_BONEYARD = 7,
- SKY_MOUNTAIN = 8,
- SKY = 9, STARRY_SKIES = 9,
- PLANET = 10, KOOPA_PLANET = 10,
- CORE = 11, KOOPA_CORE = 11,
- BONUS_LAND = 12,
- GOLDWOOD = 13, GOLDWOOD_FOREST = 13,
- MINIMEGA = 14, MINIMEGA_ISLAND = 14,
- CRYSTAL = 15, CRYSTAL_CAVES = 15,
- BOMBARD = 16, BOMBARD_CLIFFS = 16,
- SKY_CITY = 17,
- WORLD_COUNT = 18,
- UNKNOWN_WORLD = 255
-};
-
-NWRWorld NewerWorldForLevelID(int world, int level);
-
-const wchar_t *NewerWorldName(NWRWorld world);
int getStarCoinCount();
#endif /* NEWER_H */
diff --git a/src/fileselect.S b/src/fileselect.S
index 9f7f396..16a1047 100644
--- a/src/fileselect.S
+++ b/src/fileselect.S
@@ -54,8 +54,7 @@ DFNiceTitle:
bctr
.extern findTextBoxByName__Q23m2d17EmbedLayoutBase_cCFPCc
-.extern NewerWorldNames
-.extern NewerWorldCount
+.extern findPictureByName__Q23m2d17EmbedLayoutBase_cCFPCc
.extern InsertIntIntoTextBox1
.global DFNiceWorldName
DFNiceWorldName:
@@ -71,22 +70,21 @@ DFNiceWorldName:
stw r25, 0x14(r1)
mr r20, r4
- # get Newer map number
- lbz r6, 0x6FC(r31)
- lis r8, NewerWorldCount@h
- ori r8, r8, NewerWorldCount@l
- lwz r8, 0(r8)
- cmpw r6, r8
- bge invalidThing
- slwi r6, r6, 2
- lis r7, NewerWorldNames@h
- ori r7, r7, NewerWorldNames@l
- lwzx r4, r7, r6
- b gotName
-invalidThing:
- lis r4, InvalidWorld@h
- ori r4, r4, InvalidWorld@l
-gotName:
+ # Savefile is in r31
+ # World Name field is in r20
+
+ lis r4, ConvertedWorldName@h
+ ori r4, r4, ConvertedWorldName@l
+ mr r3, r4
+ mr r5, r31
+ li r6, 36
+ mtctr r6
+convWNameLoop:
+ lbz r6, 0x6FC(r5)
+ sth r6, 0(r3)
+ addi r3, r3, 2
+ addi r5, r5, 1
+ bdnz convWNameLoop
mr r3, r20
li r5, 0
@@ -95,6 +93,24 @@ gotName:
mtctr r12
bctrl
+ # now set the colours
+ # Text colours: 0x720, hint colours: 0x728
+ lwz r3, 0x720(r31)
+ stw r3, 0xDC(r20)
+ lwz r3, 0x724(r31)
+ stw r3, 0xE0(r20)
+
+ addi r3, r30, 0x74
+ lis r4, Picture_00@h
+ ori r4, r4, Picture_00@l
+ bl findPictureByName__Q23m2d17EmbedLayoutBase_cCFPCc
+ lwz r4, 0x728(r31)
+ stw r4, 0xD8(r3)
+ stw r4, 0xDC(r3)
+ lwz r4, 0x72C(r31)
+ stw r4, 0xE0(r3)
+ stw r4, 0xE4(r3)
+
# While we're at it, take care of some other things
# r21 shall hold our star coin count; r22 shall hold our exit count
# r23 shall hold the level pointer
@@ -255,10 +271,13 @@ NormalExitStr: .string "<Normal> %d-%d\n"
SecretExitStr: .string "<Secret> %d-%d\n"
StarCoinCount: .string "StarCoinCount"
ExitCount: .string "ExitCount"
+Picture_00: .string "Picture_00"
.align 4
DFTitle:
.short 'F','i','l','e',' ','X',0
-InvalidWorld:
-.short '<','I','n','v','a','l','i','d',' ','W','o','r','l','d','>',0
+ConvertedWorldName:
+.short 0,0,0,0,0,0,0,0,0,0,0,0 # 12
+.short 0,0,0,0,0,0,0,0,0,0,0,0 # 12
+.short 0,0,0,0,0,0,0,0,0,0,0,0 # 12
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");
diff --git a/src/newer.cpp b/src/newer.cpp
index 2bad8a0..0b53fa6 100644
--- a/src/newer.cpp
+++ b/src/newer.cpp
@@ -1,82 +1,6 @@
#include <newer.h>
#include <game.h>
-NWRWorld NewerWorldForLevelID(int w, int l) {
- switch (w) {
- case 1: return YOSHI_ISLAND;
- case 2:
- if (((l>1) && (l<5)) || (l==15) || (l==33) || (l==34))
- return SOGGY_SEWERS;
- else
- return RUBBLE_RUINS;
- case 3: return MUSHROOM_PEAKS;
- case 4: return SAKURA_VILLAGE;
- case 5:
- if (l<7 || l==15 || l==33 || l==34)
- return FREEZEFLAME_GLACIER;
- else
- return FREEZEFLAME_VOLCANO;
- case 6: return PUMPKIN_BONEYARD;
- case 7:
- if (l<4)
- return SKY_MOUNTAIN;
- else
- return STARRY_SKIES;
- case 8:
- if (l<6 || l==15 || l==25 || l==33 || l==34)
- return KOOPA_PLANET;
- else
- return KOOPA_CORE;
- case 9: return BONUS_LAND;
- case 10:
- if (l<6 || l==30 || l==41)
- return GOLDWOOD_FOREST;
- else if (l<11 || l==32)
- return MINIMEGA_ISLAND;
- else if (l<16 || l==33 || l==34 || l==31)
- return CRYSTAL_CAVES;
- else if (l<19)
- return BOMBARD_CLIFFS;
- else
- return SKY_CITY;
- }
-
- return UNKNOWN_WORLD;
-}
-
-
-const wchar_t *NewerWorldNames[] = {
- L"Yoshi's Island",
- L"Rubble Ruins",
- L"Soggy Sewers",
- L"Mushroom Peaks",
- L"Sakura Village",
- L"Freezeflame Glacier",
- L"Freezeflame Volcano",
- L"Pumpkin Boneyard",
- L"Sky Mountain",
- L"Starry Skies",
- L"Koopa Planet",
- L"Koopa Core",
- L"Bonus Land",
- L"Goldwood Forest",
- L"Mini-Mega Island",
- L"Crystal Caves",
- L"Bombard Cliffs",
- L"Sky City"
-};
-
-// This is an array so it can be accessed from fileselect.S
-int NewerWorldCount[] = {
- 18
-};
-
-const wchar_t *NewerWorldName(NWRWorld world) {
- if (world < 0 || world >= WORLD_COUNT)
- return L"Unknown World";
- return NewerWorldNames[world];
-}
-
int getStarCoinCount() {
SaveBlock *save = GetSaveFile()->GetBlock(-1);