Quote:
Originally Posted by Gos_pira
There are source code out there for reading the graal and zelda levels.
|
do you think you could help me find it? I think now that you mention it I remember there being .zelda files.. but no clue what version.
Ah. I see, I am not sure if we can link to the page the source came from but I do believe we can post the snippet here regarding .graal format.
PHP Code:
bool TLevel::loadGraal(const CString& pLevelName)
{
// Get the appropriate filesystem.
CFileSystem* fileSystem = server->getFileSystem();
if (server->getSettings()->getBool("nofoldersconfig", false) == false)
fileSystem = server->getFileSystem(FS_LEVEL);
// Path-To-File
actualLevelName = levelName = pLevelName;
fileName = fileSystem->find(pLevelName);
modTime = fileSystem->getModTime(pLevelName);
// Load file
CString fileData;
if (fileData.load(fileName) == false) return false;
// Grab file version.
fileVersion = fileData.readChars(8);
int v = -1;
if (fileVersion == "GR-V1.00") v = 0;
else if (fileVersion == "GR-V1.01") v = 1;
else if (fileVersion == "GR-V1.02") v = 2;
else if (fileVersion == "GR-V1.03") v = 3;
if (v == -1) return false;
// Load tiles.
{
int bits = (v > 0 ? 13 : 12);
int read = 0;
unsigned int buffer = 0;
unsigned short code = 0;
short tiles[2] = {-1,-1};
int boardIndex = 0;
int count = 1;
bool doubleMode = false;
// Read the tiles.
while (boardIndex < 64*64 && fileData.bytesLeft() != 0)
{
// Every control code/tile is either 12 or 13 bits. WTF.
// Read in the bits.
while (read < bits)
{
buffer += ((unsigned char)fileData.readChar()) << read;
read += 8;
}
// Pull out a single 12/13 bit code from the buffer.
code = buffer & (bits == 12 ? 0xFFF : 0x1FFF);
buffer >>= bits;
read -= bits;
// See if we have an RLE control code.
// Control codes determine how the RLE scheme works.
if (code & (bits == 12 ? 0x800 : 0x1000))
{
// If the 0x100 bit is set, we are in a double repeat mode.
// {double 4}56 = 56565656
if (code & 0x100) doubleMode = true;
// How many tiles do we count?
count = code & 0xFF;
continue;
}
// If our count is 1, just read in a tile. This is the default mode.
if (count == 1)
{
levelTiles[boardIndex++] = (short)code;
continue;
}
// If we reach here, we have an RLE scheme.
// See if we are in double repeat mode or not.
if (doubleMode)
{
// Read in our first tile.
if (tiles[0] == -1)
{
tiles[0] = (short)code;
continue;
}
// Read in our second tile.
tiles[1] = (short)code;
// Add the tiles now.
for (int i = 0; i < count && boardIndex < 64*64-1; ++i)
{
levelTiles[boardIndex++] = tiles[0];
levelTiles[boardIndex++] = tiles[1];
}
// Clean up.
tiles[0] = tiles[1] = -1;
doubleMode = false;
count = 1;
}
// Regular RLE scheme.
else
{
for (int i = 0; i < count && boardIndex < 64*64; ++i)
levelTiles[boardIndex++] = (short)code;
count = 1;
}
}
}
// Load the links.
{
while (fileData.bytesLeft())
{
CString line = fileData.readString("\n");
if (line.length() == 0 || line == "#") break;
// Assemble the level string.
std::vector<CString> vline = line.tokenize();
CString level = vline[0];
if (vline.size() > 7)
{
for (unsigned int i = 0; i < vline.size() - 7; ++i)
level << " " << vline[1 + i];
}
if (fileSystem->find(level).isEmpty())
continue;
levelLinks.push_back(new TLevelLink(vline));
}
}
// Load the baddies.
{
while (fileData.bytesLeft())
{
signed char x = fileData.readChar();
signed char y = fileData.readChar();
signed char type = fileData.readChar();
// Ends with an invalid baddy.
if (x == -1 && y == -1 && type == -1)
{
fileData.readString("\n"); // Empty verses.
break;
}
// Add the baddy.
TLevelBaddy* baddy = addBaddy((float)x, (float)y, type);
if (baddy == 0)
continue;
// Load the verses.
std::vector<CString> bverse = fileData.readString("\n").tokenize("\\");
CString props;
for (char j = 0; j < (char)bverse.size(); ++j)
props >> (char)(BDPROP_VERSESIGHT + j) >> (char)bverse[j].length() << bverse[j];
if (props.length() != 0) baddy->setProps(props);
}
}
// Load NPCs.
{
while (fileData.bytesLeft())
{
CString line = fileData.readString("\n");
if (line.length() == 0 || line == "#") break;
signed char x = line.readGChar();
signed char y = line.readGChar();
CString image = line.readString("#");
CString code = line.readString("");
TNPC* npc = server->addNPC(image, code, x, y, this, true, false);
levelNPCs.push_back(npc);
}
}
// Load chests.
if (v > 0)
{
while (fileData.bytesLeft())
{
CString line = fileData.readString("\n");
if (line.length() == 0 || line == "#") break;
signed char x = line.readGChar();
signed char y = line.readGChar();
signed char item = line.readGChar();
signed char signindex = line.readGChar();
levelChests.push_back(new TLevelChest(x, y, item, signindex));
}
}
// Load signs.
{
while (fileData.bytesLeft())
{
CString line = fileData.readString("\n");
if (line.length() == 0) break;
signed char x = line.readGChar();
signed char y = line.readGChar();
CString text = line.readString("");
levelSigns.push_back(new TLevelSign(x, y, text, true));
}
}
return true;
}
I would still like to visually see with a hex editor how this data read/write.