while (sscanf(remainder, "%s%n", buf, &consumed) == 1) {
string value;
string flag = buf;
size_t eqAt = flag.find('=');
if (eqAt != string::npos) {
value = flag.substr(eqAt + 1);
flag.erase(eqAt);
}
switch (hash(flag)) {
case str_case(flag, "Blends") {
tileProp.blends = true;
break;
}
case str_case(flag, "Framed") {
tileProp.isFramed = true;
break;
}
case str_case(flag, "UnFramed") {
break;
}
case str_case(flag, "Solid") {
tileProp.isSolid = true;
break;
}
case str_case(flag, "SolidTop") {
tileProp.topIsSolid = true;
break;
}
case str_case(flag, "Platform") {
tileProp.isPlatform = true;
break;
}
case str_case(flag, "Merge") {
tileProp.blendWith = atol(value.c_str());
break;
}
case str_case(flag, "Stone") {
tileProp.isStone = true;
break;
}
case str_case(flag, "Grass") {
tileProp.isGrass = true;
break;
}
case str_case(flag, "OnCeil") {
tileProp.placement = TilePlacement::ON_CEILING;
break;
}
case str_case(flag, "OnFaces") {
tileProp.placement = TilePlacement::ON_FACES;
break;
}
case str_case(flag, "OnFloorSurf") {
tileProp.placement = TilePlacement::ON_FACES;
break;
}
case str_case(flag, "OnFloor") {
tileProp.placement = TilePlacement::ON_FLOOR;
break;
}
case str_case(flag, "OnSurf") {
tileProp.placement = TilePlacement::ON_SURFACES;
break;
}
case str_case(flag, "OnTorch") {
tileProp.placement = TilePlacement::ON_TORCH_PTS;
break;
}
case str_case(flag, "OnWall") {
tileProp.placement = TilePlacement::ON_WALLS;
break;
}
case str_case(flag, "AsDoor") {
tileProp.placement = TilePlacement::AS_DOOR;
break;
}
case str_case(flag, "Light") {
tileProp.isLightSource = true;
break;
}
case str_case(flag, "TX") {
tileProp.tX = atol(value.c_str());
break;
}
case str_case(flag, "TY") {
tileProp.tY = atol(value.c_str());
break;
}
default:
fprintf(stderr, "Unknown flag %s\n", flag.c_str());
return 2;
}
remainder += consumed;
}
// The magic
constexpr int filthyHash(const char *x, int y, int z, int res) {
return z < y
? filthyHash(x, y, z + 1, (int)((long)res * 31 + x[z]))
: res;
}
constexpr int cleanHash(const char* x, int y) {
return filthyHash(x, y, 0, 0) << 4 | (y & ((1 << 4) - 1));
}
template<size_t N> constexpr int dirtyHash(const char (&x)[N]) {
return cleanHash(x, N - 1);
}
int hash(string x) {
return cleanHash(x.c_str(), x.length());
}
#define str_case(key, x) dirtyHash(x): if ((key) == (x))
Comments
0 B
|👍
/👎