forked from mrkite/minutor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
chunkloader.cpp
60 lines (51 loc) · 1.33 KB
/
chunkloader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/** Copyright (c) 2013, Sean Kasun */
#include "./chunkloader.h"
#include "./chunkcache.h"
#include "./chunk.h"
ChunkLoader::ChunkLoader(QString path, int cx, int cz)
: path(path)
, cx(cx), cz(cz)
, cache(ChunkCache::Instance())
{}
ChunkLoader::~ChunkLoader()
{}
void ChunkLoader::run() {
// get coordinates of Region file
int rx = cx >> 5;
int rz = cz >> 5;
QFile f(path + "/region/r." + QString::number(rx) + "." +
QString::number(rz) + ".mca");
if (!f.open(QIODevice::ReadOnly)) { // no chunks in this region
emit loaded(cx, cz);
return;
}
// map header into memory
uchar *header = f.map(0, 4096);
int offset = 4 * ((cx & 31) + (cz & 31) * 32);
int coffset = (header[offset] << 16) | (header[offset + 1] << 8) |
header[offset + 2];
int numSectors = header[offset+3];
f.unmap(header);
if (coffset == 0) { // no chunk
f.close();
emit loaded(cx, cz);
return;
}
uchar *raw = f.map(coffset * 4096, numSectors * 4096);
if (raw == NULL) {
f.close();
emit loaded(cx, cz);
return;
}
// get existing Chunk entry from Cache
QSharedPointer<Chunk> chunk(cache.fetchCached(cx, cz));
// parse Chunk data
// Chunk will be flagged "loaded" in a thread save way
if (chunk) {
NBT nbt(raw);
chunk->load(nbt);
}
f.unmap(raw);
f.close();
emit loaded(cx, cz);
}