diff options
Diffstat (limited to 'src/randtiles.cpp')
| -rw-r--r-- | src/randtiles.cpp | 65 | 
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;
  		}
  	}
 | 
