-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInfdevZone.hexpat
More file actions
140 lines (110 loc) · 4 KB
/
InfdevZone.hexpat
File metadata and controls
140 lines (110 loc) · 4 KB
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#pragma author DexrnZacAttack
#pragma description Minecraft Infdev 20100624 Zone File
#pragma repo https://github.com/Team-Lodestone/ImHex-Patterns
#pragma version 1.0.0
#pragma magic [13 73 70 00] @ 0x00
#pragma endian big
import std.core;
import std.io;
import type.magic;
using long = s64;
using int = s32;
using short = s16;
using byte = s8;
bitfield u4 {
low : 4;
high : 4;
} [[static, inline]];
namespace InfdevZone {
using ZoneFile;
namespace Slot {
int CHUNKS_PER_ZONE_BITS = 5;
int CHUNKS_PER_ZONE = 1 << CHUNKS_PER_ZONE_BITS;
int CHUNK_WIDTH = 16;
int CHUNK_DEPTH = 16;
int CHUNK_HEIGHT = 128;
int CHUNK_HEADER_SIZE = 256;
int CHUNK_SIZE = CHUNK_WIDTH * CHUNK_DEPTH * CHUNK_HEIGHT;
int CHUNK_LAYERS = 3;
int CHUNK_SIZE_BYTES = CHUNK_SIZE * CHUNK_LAYERS + CHUNK_HEADER_SIZE;
/** Returns a slot from chunk coords
*
* @param cx Chunk X coordinate
* @param cz Chunk Z coordinate
* @return A slot for the given coords
*/
fn getSlot(int cx, int cz) {
int zoneX = cx >> CHUNKS_PER_ZONE_BITS;
int zoneZ = cz >> CHUNKS_PER_ZONE_BITS;
int offX = cx - (zoneX << CHUNKS_PER_ZONE_BITS);
int offZ = cz - (zoneZ << CHUNKS_PER_ZONE_BITS);
return offX + offZ * CHUNKS_PER_ZONE;
};
bitfield Properties {
unused : 63 [[hidden]];
terrainPopulated : 1;
};
struct Header {
int x;
int z;
long inhabitedTime;
Properties properties;
padding[CHUNK_HEADER_SIZE - ($ - addressof(this))];
};
// or should this be called Chunk?
// We need to figure out the actual terminology lmao
struct Slot {
InfdevZone::Slot::Header header [[inline]];
byte blocks[CHUNK_SIZE];
u4 data[CHUNK_SIZE / 2];
u4 skyLight[CHUNK_SIZE / 2];
u4 blockLight[CHUNK_SIZE / 2];
byte heightmap[CHUNK_WIDTH * CHUNK_DEPTH] [[hex::visualize("bitmap", this, CHUNK_WIDTH, CHUNK_DEPTH)]];
} [[name(std::format("Chunk @ {}, {}", header.x, header.z))]];
}
namespace ZoneFile {
int FILE_HEADER_SIZE = 4096;
int MAGIC_NUMBER = 0x13737000;
int VERSION = 0x0000;
struct Header {
int magic;
if (magic != MAGIC_NUMBER) {
std::error(std::format("Magic value '{:#04x}' does not match expected magic '{:#04x}'", magic, MAGIC_NUMBER));
}
short version;
if (version != VERSION) {
std::error(std::format("Version '{:#02x}' does not match expected version '{:#02x}'", version, VERSION));
}
short slotCount;
short slotLocations[slotCount];
};
/** Returns the offset in the data where a slot should be written
*
* @param slot The slot to get the offset of
*/
fn getSlotOffset(int slot) {
return (slot - 1) * CHUNK_SIZE_BYTES + FILE_HEADER_SIZE;
};
struct SlotElement {
// std::print("{}", std::core::array_index());
int loc = parent.header.slotLocations[std::core::array_index()];
u64 idx = InfdevZone::ZoneFile::getSlotOffset(loc);
if (idx != 0 && idx <= std::mem::size()) {
InfdevZone::Slot::Slot slot @ idx;
} else {
if (idx == 0) {
std::warning(std::format("Skipping empty slot"));
} else {
std::warning(std::format("Skipping invalid slot {} (would place at index {:#06x})", loc, idx));
}
}
} [[inline]];
struct ZoneFile {
InfdevZone::ZoneFile::Header header [[inline]];
InfdevZone::ZoneFile::SlotElement slots[header.slotCount];
};
}
}
#ifndef INF624_ZONE_USE_LIB
InfdevZone::ZoneFile::ZoneFile zone @ 0x00;
#endif