summaryrefslogtreecommitdiff
path: root/src/randtiles.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/randtiles.cpp65
1 files changed, 57 insertions, 8 deletions
diff --git a/src/randtiles.cpp b/src/randtiles.cpp
index 92e31ae..34e2daf 100644
--- a/src/randtiles.cpp
+++ b/src/randtiles.cpp
@@ -9,6 +9,34 @@ public:
CHECK_BOTH = 3
};
+ enum Special {
+ SP_NONE = 0,
+ SP_VDOUBLE_TOP = 1,
+ SP_VDOUBLE_BOTTOM = 2
+ };
+
+ class NameList {
+ public:
+ u32 count;
+ u32 offsets[1]; // variable size
+
+ const char *getName(int index) {
+ return ((char*)this) + offsets[index];
+ }
+
+ bool contains(const char *name) {
+ OSReport("NameList[%p] with %d names being compared against %s\n", this, count, name);
+ for (int i = 0; i < count; i++) {
+ OSReport("Checking %s\n", getName(i));
+ if (strcmp(name, getName(i)) == 0)
+ return true;
+ OSReport("Did not pass\n");
+ }
+
+ return false;
+ }
+ };
+
class Entry {
public:
u8 lowerBound, upperBound;
@@ -22,12 +50,12 @@ public:
class Section {
public:
- u32 nameOffset;
+ u32 nameListOffset;
u32 entryCount;
Entry entries[1]; // variable size
- const char *getName() {
- return ((char*)this) + nameOffset;
+ NameList *getNameList() {
+ return (NameList*)(((u32)this) + nameListOffset);
}
};
@@ -54,9 +82,8 @@ RandomTileData::Section *RandomTileData::getSection(const char *name) {
for (int i = 0; i < sectionCount; i++) {
RandomTileData::Section *sect = getSection(i);
- if (strcmp(name, sect->getName()) == 0) {
+ if (sect->getNameList()->contains(name))
return sect;
- }
}
return 0;
@@ -76,7 +103,7 @@ extern "C" bool RandTileLoadHook() {
OSReport("Failed.\n");
return false;
} else {
- OSReport("Successfully loaded RandTiles.bin.\n");
+ OSReport("Successfully loaded RandTiles.bin [%p].\n", buf);
RandomTileData::instance = (RandomTileData*)buf;
return true;
}
@@ -90,6 +117,7 @@ extern "C" void IdentifyTilesets(RTilemapClass *self) {
const char *tilesetName = BGDatClass::instance->getTilesetName(self->areaID, i);
self->sections[i] = RandomTileData::instance->getSection(tilesetName);
+ OSReport("[%d] Chose %p for %s\n", i, self->sections[i], tilesetName);
}
}
@@ -108,24 +136,38 @@ extern "C" void TryAndRandomise(RTilemapClass *self, BGRender *bgr) {
if (tile >= entry->lowerBound && tile <= entry->upperBound) {
// Found it!!
// Try to make one until we meet the conditions
+ u8 type = entry->type & 3;
+ u8 special = entry->type >> 2;
+
u8 *tileNums = entry->getTileNums();
u16 chosen = 0xFF;
+ // If it's the top special, then ignore this tile, we'll place that one
+ // once we choose the bottom one
+ if (special == RandomTileData::SP_VDOUBLE_TOP)
+ break;
+
u16 *top = 0, *left = 0, *right = 0, *bottom = 0;
- if (entry->type == RandomTileData::CHECK_HORZ || entry->type == RandomTileData::CHECK_BOTH) {
+ if (type == RandomTileData::CHECK_HORZ || type == RandomTileData::CHECK_BOTH) {
left = self->getPointerToTile(bgr->curX - 1, bgr->curY);
right = self->getPointerToTile(bgr->curX + 1, bgr->curY);
}
- if (entry->type == RandomTileData::CHECK_VERT || entry->type == RandomTileData::CHECK_BOTH) {
+ if (type == RandomTileData::CHECK_VERT || type == RandomTileData::CHECK_BOTH) {
top = self->getPointerToTile(bgr->curX, bgr->curY - 1);
bottom = self->getPointerToTile(bgr->curX, bgr->curY + 1);
}
+ int attempts = 0;
while (true) {
// is there even a point to using that special random function?
chosen = (tileset << 8) | tileNums[MakeRandomNumberForTiles(entry->count)];
+ // avoid infinite loops
+ attempts++;
+ if (attempts > 5)
+ break;
+
if (top != 0 && *top == chosen)
continue;
if (bottom != 0 && *bottom == chosen)
@@ -139,6 +181,13 @@ extern "C" void TryAndRandomise(RTilemapClass *self, BGRender *bgr) {
bgr->tileToPlace = chosen;
+ if (special == RandomTileData::SP_VDOUBLE_BOTTOM) {
+ if (top == 0)
+ top = self->getPointerToTile(bgr->curX, bgr->curY - 1);
+
+ *top = (chosen - 0x10);
+ }
+
return;
}
}