From c87e98e07df9554c0a33043d289d139b6aeb5699 Mon Sep 17 00:00:00 2001 From: Treeki Date: Sun, 14 Aug 2011 00:31:04 +0200 Subject: upgraded the random tile engine and added lots of defs --- src/randtiles.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 8 deletions(-) (limited to 'src') 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; } } -- cgit v1.2.3