summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2012-07-25 14:10:39 +0200
committerTreeki <treeki@gmail.com>2012-07-25 14:10:39 +0200
commit6895c831ad320c14b01ccabe1c8adcec354e3f9f (patch)
treea47ec4a7b2ce494c668771975e4880ada1d3557c
parent0d20c172706178e5df2d426fcf5cb1b7ae85c225 (diff)
downloadkamek-6895c831ad320c14b01ccabe1c8adcec354e3f9f.tar.gz
kamek-6895c831ad320c14b01ccabe1c8adcec354e3f9f.zip
lots more work completed, basic unlocks workingfreeform-unlocks
-rw-r--r--kamek_pal.x1
-rw-r--r--src/koopatlas/core.cpp5
-rw-r--r--src/koopatlas/map.cpp35
-rw-r--r--src/koopatlas/map.h5
-rw-r--r--src/koopatlas/mapdata.cpp32
-rw-r--r--src/koopatlas/mapdata.h29
-rw-r--r--src/koopatlas/pathmanager.cpp114
-rw-r--r--src/koopatlas/pathmanager.h8
8 files changed, 179 insertions, 50 deletions
diff --git a/kamek_pal.x b/kamek_pal.x
index 16996cb..7978605 100644
--- a/kamek_pal.x
+++ b/kamek_pal.x
@@ -261,6 +261,7 @@ SECTIONS {
__nw__FUl = 0x802B9350;
__dl__FPv = 0x802B93C0;
+ __dla__FPv = 0x802B93D0;
__construct_new_array = 0x802DCAD0;
__destroy_new_array = 0x802DCE00;
diff --git a/src/koopatlas/core.cpp b/src/koopatlas/core.cpp
index 42bf7c1..2317d00 100644
--- a/src/koopatlas/core.cpp
+++ b/src/koopatlas/core.cpp
@@ -973,6 +973,11 @@ void NewerMapDrawFunc() {
DrawOpa();
DrawXlu();
UnlinkScene(1);
+ SetCurrentCameraID(0);
+ for (int i = 0; i < 4; i++)
+ RenderEffects(0, 0xB+i);
+ for (int i = 0; i < 4; i++)
+ RenderEffects(0, 7+i);
GXDrawDone();
// Leaving out some stuff here
DrawAllLayoutsAfterX(0x80);
diff --git a/src/koopatlas/map.cpp b/src/koopatlas/map.cpp
index 4d2bc1d..2486d34 100644
--- a/src/koopatlas/map.cpp
+++ b/src/koopatlas/map.cpp
@@ -45,7 +45,6 @@ int dWMMap_c::onCreate() {
renderer.allocator.setup(GameHeaps[0], 0x20);
bool result = renderer.setup(&renderer.allocator);
- bgMatrix.identity();
bgMatrix.translation(0.0f, 0.0f, -500.0f);
allocator.link(-1, GameHeaps[0], 0, 0x20);
@@ -112,34 +111,21 @@ void dWMMap_c::renderer_c::drawLayers() {
beginRendering();
- bool cont = false;
for (int iLayer = data->layerCount - 1; iLayer >= 0; iLayer--) {
dKPLayer_s *layer = data->layers[iLayer];
renderMtx[2][3] += 2.0f;
- cont = false;
- for (int iNodes = dataCls->pathLayer->nodeCount - 1; iNodes >= 0; iNodes--) {
- dKPNode_s *node = dataCls->pathLayer->nodes[iNodes];
- bool unlock = node->isUnlocked();
- if (!unlock) {
- if (node->tileLayer == layer) { cont = true; break; }
- if (node->doodadLayer == layer) { cont = true; break; }
- }
- }
- for (int iPaths = dataCls->pathLayer->pathCount - 1; iPaths >= 0; iPaths--) {
- dKPPath_s *path = dataCls->pathLayer->paths[iPaths];
- if (!path->isAvailable) {
- if (path->tileLayer == layer) { cont = true; break; }
- if (path->doodadLayer == layer) { cont = true; break; }
- }
- }
+ if (layer->alpha == 0)
+ continue; // invisible
- if (cont) { continue; }
TileReport("Checking layer %d with type %d\n", iLayer, layer->type);
+
+ GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,layer->alpha});
+
if (layer->type == dKPLayer_s::OBJECTS)
- renderTileLayer(layer, data->sectors, 255);
+ renderTileLayer(layer, data->sectors);
else if (layer->type == dKPLayer_s::DOODADS)
- renderDoodadLayer(layer, 255);
+ renderDoodadLayer(layer);
}
endRendering();
@@ -209,7 +195,7 @@ void dWMMap_c::renderer_c::beginRendering() {
GXSetTevColor(GX_TEVREG1, (GXColor){0,0,0,255});
}
-void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sectors, int alpha) {
+void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sectors) {
//TileReport("Rendering layer %p\n", layer);
// don't render it if we don't need to
@@ -288,8 +274,6 @@ void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector
float coordY2 = yMult * (tileY + 26.0f);
- GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,alpha});
-
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
GXPosition2s16(worldX + 24, worldY - 24);
GXTexCoord2f32(coordX2, coordY2);
@@ -310,7 +294,7 @@ void dWMMap_c::renderer_c::renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector
//TileReport("Layer complete\n");
}
-void dWMMap_c::renderer_c::renderDoodadLayer(dKPLayer_s *layer, int alpha) {
+void dWMMap_c::renderer_c::renderDoodadLayer(dKPLayer_s *layer) {
for (int i = 0; i < layer->doodadCount; i++) {
dKPDoodad_s *doodad = layer->doodads[i];
DoodadReport("Doodad @ %f,%f sized %f,%f with angle %f\n", doodad->x, doodad->y, doodad->width, doodad->height, doodad->angle);
@@ -430,7 +414,6 @@ void dWMMap_c::renderer_c::renderDoodadLayer(dKPLayer_s *layer, int alpha) {
loadCamera(doodadMtx);
loadTexture(doodad->texObj);
- GXSetTevColor(GX_TEVREG0, (GXColor){255,255,255,alpha});
GXBegin(GX_QUADS, GX_VTXFMT1, 4);
GXPosition2f32(halfW, -halfH);
GXTexCoord2u8(255, 255);
diff --git a/src/koopatlas/map.h b/src/koopatlas/map.h
index 14c2b87..8d3e2ae 100644
--- a/src/koopatlas/map.h
+++ b/src/koopatlas/map.h
@@ -42,8 +42,8 @@ class dWMMap_c : public dBase_c {
void beginRendering();
void endRendering();
- void renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sector, int alpha);
- void renderDoodadLayer(dKPLayer_s *layer, int alpha);
+ void renderTileLayer(dKPLayer_s *layer, dKPLayer_s::sector_s *sector);
+ void renderDoodadLayer(dKPLayer_s *layer);
void loadTexture(GXTexObj *obj);
@@ -55,7 +55,6 @@ class dWMMap_c : public dBase_c {
float baseZ;
int minX, minY, maxX, maxY;
- int unlockingAlpha;
};
renderer_c renderer;
diff --git a/src/koopatlas/mapdata.cpp b/src/koopatlas/mapdata.cpp
index 650f1e3..63fd0b7 100644
--- a/src/koopatlas/mapdata.cpp
+++ b/src/koopatlas/mapdata.cpp
@@ -2,17 +2,31 @@
// HELPER FUNCTIONS
-dKPPath_s *dKPNode_s::getOppositeExitTo(dKPPath_s *path) {
+dKPPath_s *dKPNode_s::getOppositeExitTo(dKPPath_s *path, bool mustBeAvailable) {
for (int i = 0; i < 4; i++) {
dKPPath_s *check = exits[i];
- if (check != 0 && check != path)
+ if (check != 0 && check != path) {
+ if (mustBeAvailable && !check->isAvailable)
+ continue;
+
return check;
+ }
}
return 0;
}
+int dKPNode_s::getExitCount(bool mustBeAvailable) {
+ int ct = 0;
+
+ for (int i = 0; i < 4; i++)
+ if (exits[i] && (mustBeAvailable ? exits[i]->isAvailable : true))
+ ct++;
+
+ return ct;
+}
+
bool dKPNode_s::isUnlocked() {
for (int i = 0; i < 4; i++)
if (exits[i])
@@ -89,6 +103,20 @@ void dKPNode_s::setupNodeExtra() {
this->extra->mallocator.unlink();
}
+void dKPNode_s::setLayerAlpha(u8 alpha) {
+ if (tileLayer)
+ tileLayer->alpha = alpha;
+ if (doodadLayer)
+ doodadLayer->alpha = alpha;
+}
+
+void dKPPath_s::setLayerAlpha(u8 alpha) {
+ if (tileLayer)
+ tileLayer->alpha = alpha;
+ if (doodadLayer)
+ doodadLayer->alpha = alpha;
+}
+
int dKPLayer_s::findNodeID(dKPNode_s *node) {
for (int i = 0; i < nodeCount; i++)
if (nodes[i] == node)
diff --git a/src/koopatlas/mapdata.h b/src/koopatlas/mapdata.h
index 48a1720..40e1a43 100644
--- a/src/koopatlas/mapdata.h
+++ b/src/koopatlas/mapdata.h
@@ -70,6 +70,8 @@ struct dKPNode_s {
NodeTypes type;
+ bool isNew;
+
dKPNodeExtra_c *extra;
// The union is placed at the very end so we can leave out padding in the
@@ -89,24 +91,37 @@ struct dKPNode_s {
bool isUnlocked();
void setupNodeExtra();
- dKPPath_s *getOppositeExitTo(dKPPath_s *path);
+ dKPPath_s *getOppositeExitTo(dKPPath_s *path, bool mustBeAvailable=false);
+ dKPPath_s *getOppositeAvailableExitTo(dKPPath_s *path) {
+ return getOppositeExitTo(path, true);
+ }
+
+ int getExitCount(bool mustBeAvailable=false);
+ int getAvailableExitCount() {
+ return getExitCount(true);
+ }
+
+ void setLayerAlpha(u8 alpha);
};
struct dKPPath_s {
enum Availability {
NOT_AVAILABLE = 0,
AVAILABLE = 1,
- NEWLY_AVAILABLE = 2
+ NEWLY_AVAILABLE = 2,
+ ALWAYS_AVAILABLE = 3
};
dKPNode_s *start, *end;
dKPLayer_s *tileLayer, *doodadLayer;
- u8 isAvailable; // computed on-the-fly - default from Koopatlas is 1
- u8 hasSecret;
+ u8 isAvailable; // computed on-the-fly - default from Koopatlas is NOT or ALWAYS
+ u8 isSecret;
u8 _padding[2];
float speed;
int animation;
+
+ void setLayerAlpha(u8 alpha);
};
/******************************************************************************
@@ -118,6 +133,8 @@ struct dKPLayer_s {
};
LayerTypes type;
+ u8 alpha;
+ u8 _padding[3];
typedef u16 sector_s[16][16];
@@ -180,7 +197,7 @@ class dKPMapData_c {
template <typename T>
inline T* fixRef(T*& indexAsPtr) {
unsigned int index = (unsigned int)indexAsPtr;
- if (index == 0xFFFFFFFF)
+ if (index == 0xFFFFFFFF || index == 0)
indexAsPtr = 0;
else
indexAsPtr = (T*)(((char*)data) + index);
@@ -190,7 +207,7 @@ class dKPMapData_c {
template <typename T>
inline T* fixRefSafe(T*& indexAsPtr) {
unsigned int index = (unsigned int)indexAsPtr;
- if (index == 0xFFFFFFFF)
+ if (index == 0xFFFFFFFF || index == 0)
indexAsPtr = 0;
else if (index < 0x80000000)
indexAsPtr = (T*)(((char*)data) + index);
diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp
index 4eb6c2d..ee7b596 100644
--- a/src/koopatlas/pathmanager.cpp
+++ b/src/koopatlas/pathmanager.cpp
@@ -68,21 +68,40 @@ void dWMPathManager_c::setup() {
}
static u8 *PathAvailabilityData = 0;
+static u8 *NodeAvailabilityData = 0;
dWMPathManager_c::~dWMPathManager_c() {
if (PathAvailabilityData && !isEnteringLevel) {
delete[] PathAvailabilityData;
PathAvailabilityData = 0;
+
+ delete[] NodeAvailabilityData;
+ NodeAvailabilityData = 0;
}
}
void dWMPathManager_c::unlockPaths() {
- u8 *oldAvData = PathAvailabilityData;
+ u8 *oldPathAvData = PathAvailabilityData;
PathAvailabilityData = new u8[pathLayer->pathCount];
+ u8 *oldNodeAvData = NodeAvailabilityData;
+ NodeAvailabilityData = new u8[pathLayer->nodeCount];
+
+ OSReport("Unlocking paths\n");
+
// unlock all needed paths
- for (int i = 0; i < pathLayer->pathCount; i++)
- PathAvailabilityData[i] = dKPPath_s::NOT_AVAILABLE;
+ for (int i = 0; i < pathLayer->pathCount; i++) {
+ dKPPath_s *path = pathLayer->paths[i];
+
+ PathAvailabilityData[i] = path->isAvailable;
+
+ //OSReport("Path %d: %d\n", i, path->isAvailable);
+ // if this path is not "always available", then nuke its alpha
+ path->setLayerAlpha((path->isAvailable == dKPPath_s::ALWAYS_AVAILABLE) ? 255 : 0);
+ }
+
+ for (int i = 0; i < pathLayer->nodeCount; i++)
+ NodeAvailabilityData[i] = pathLayer->nodes[i]->isUnlocked();
SaveBlock *save = GetSaveFile()->GetBlock(-1);
@@ -91,6 +110,7 @@ void dWMPathManager_c::unlockPaths() {
while (*in != 0) {
// begin processing a block
bool value = evaluateUnlockCondition(in, save);
+ //OSReport("Unlock condition: %d\n", value);
// get what it's supposed to affect
// for now we'll assume that it affects one or more paths
@@ -102,27 +122,55 @@ void dWMPathManager_c::unlockPaths() {
u16 pathID = (one << 8) | two;
dKPPath_s *path = pathLayer->paths[pathID];
- path->isAvailable = dKPPath_s::AVAILABLE;
- PathAvailabilityData[pathID] = dKPPath_s::AVAILABLE;
+ path->isAvailable = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE;
+ PathAvailabilityData[pathID] = value ? dKPPath_s::AVAILABLE : dKPPath_s::NOT_AVAILABLE;
+ //OSReport("Applied to path %p[%d]\n", path, pathID);
// NEWLY_AVAILABLE is set later, when that stuff is figured out
+
+ path->setLayerAlpha(value ? 255 : 0);
}
}
// did anything become newly available?!
- int whatsNew = 0;
+ newlyAvailablePaths = 0;
+ newlyAvailableNodes = 0;
- if (oldAvData) {
+ if (oldPathAvData) {
for (int i = 0; i < pathLayer->pathCount; i++) {
- if ((PathAvailabilityData[i] > 0) && (oldAvData[i] == 0)) {
+ if ((PathAvailabilityData[i] > 0) && (oldPathAvData[i] == 0)) {
dKPPath_s *path = pathLayer->paths[i];
path->isAvailable = dKPPath_s::NEWLY_AVAILABLE;
- whatsNew++;
+ newlyAvailablePaths++;
+
+ // set this path's alpha to 0, we'll fade it in later
+ path->setLayerAlpha(0);
}
}
- delete[] oldAvData;
+ delete[] oldPathAvData;
+
+ // check nodes too
+ for (int i = 0; i < pathLayer->nodeCount; i++) {
+ if ((NodeAvailabilityData[i] > 0) && (oldNodeAvData[i] == 0)) {
+ dKPNode_s *node = pathLayer->nodes[i];
+ node->isNew = true;
+ newlyAvailableNodes++;
+ }
+ }
+ delete[] oldNodeAvData;
+ }
+
+ // now set all node alphas
+ for (int i = 0; i < pathLayer->nodeCount; i++) {
+ dKPNode_s *node = pathLayer->nodes[i];
+
+ node->setLayerAlpha((node->isUnlocked() & !node->isNew) ? 255 : 0);
}
- // todo: set a flag on Map to do the path fade/sound, with whatsNew
+ // if anything was new, set it as such
+ if (newlyAvailablePaths || newlyAvailableNodes) {
+ countdownToFadeIn = 30;
+ }
+ unlockingAlpha = -1;
}
bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save) {
@@ -186,6 +234,36 @@ void dWMPathManager_c::execute() {
else if (nowPressed & WPAD_TWO)
activatePoint();
}
+
+ // handle path fading
+ if (countdownToFadeIn > 0) {
+ countdownToFadeIn--;
+ if (countdownToFadeIn <= 0)
+ unlockingAlpha = 0;
+ }
+
+ if (unlockingAlpha != -1) {
+ unlockingAlpha += 3;
+
+ for (int i = 0; i < pathLayer->pathCount; i++) {
+ dKPPath_s *path = pathLayer->paths[i];
+
+ if (path->isAvailable == dKPPath_s::NEWLY_AVAILABLE)
+ path->setLayerAlpha(unlockingAlpha);
+ }
+
+ for (int i = 0; i < pathLayer->nodeCount; i++) {
+ dKPNode_s *node = pathLayer->nodes[i];
+
+ if (node->isNew)
+ node->setLayerAlpha(unlockingAlpha);
+ }
+
+ if (unlockingAlpha == 255) {
+ // we've reached the end
+ unlockingAlpha = -1;
+ }
+ }
}
@@ -404,6 +482,16 @@ void dWMPathManager_c::moveThroughPath() {
SpammyReport("reached path end (%p)\n", to);
+ // Quick check: do we *actually* need to stop on this node?
+ // If it's a junction with more than two exits, but only two are open,
+ // take the opposite open one
+ bool stopOverride = false;
+
+ if (to->type == dKPNode_s::STOP) {
+ if (to->getExitCount() > 2 && to->getAvailableExitCount() == 2)
+ stopOverride = true;
+ }
+
if (to->type == dKPNode_s::CHANGE) {
// Go to another map
isMoving = false;
@@ -415,7 +503,7 @@ void dWMPathManager_c::moveThroughPath() {
DoSceneChange(WORLD_MAP, 0x10000000 | to->foreignID, 0);
- } else if (to->type != dKPNode_s::PASS_THROUGH) {
+ } else if (to->type != dKPNode_s::PASS_THROUGH && !stopOverride) {
// Stop here
player->startAnimation(0, 1.2, 10.0, 0.0);
player->hasEffect = false;
@@ -431,7 +519,7 @@ void dWMPathManager_c::moveThroughPath() {
dWMHud_c::instance->showPointBar();
SpammyReport("Point bar shown\n");
} else {
- startMovementTo(to->getOppositeExitTo(currentPath));
+ startMovementTo(to->getOppositeAvailableExitTo(currentPath));
SpammyReport("passthrough node, continuing to next path\n");
}
}
diff --git a/src/koopatlas/pathmanager.h b/src/koopatlas/pathmanager.h
index 5d35f4c..2ce0e9c 100644
--- a/src/koopatlas/pathmanager.h
+++ b/src/koopatlas/pathmanager.h
@@ -14,6 +14,8 @@ class dWMPathManager_c {
void execute();
bool canUseExit(dKPPath_s *path) {
+ OSReport("Checking usability of path %p\n", path);
+ if (path) OSReport("Availability: %d\n", path->isAvailable);
return (path != 0) && (path->isAvailable);
}
@@ -38,6 +40,12 @@ class dWMPathManager_c {
bool mustComplainToMapCreator;
+ int newlyAvailablePaths;
+ int newlyAvailableNodes;
+
+ int unlockingAlpha; // -1 if not used
+ int countdownToFadeIn;
+
private:
void unlockPaths();
bool evaluateUnlockCondition(u8 *&in, SaveBlock *save);