As I was working on finishing the loading code, see the Missing Code topic for more information, I was able to verify a few things about the coordinate systems used in Daggerfall.
Each location has a unique position on the world map – which, as you already know, is 1000×500 pixels in size. Each “pixel” on this map is exactly 32768 Daggerfall units on each side. Given the height of the character, 75 Daggerfall units, the original estimate of 1 inch per unit seems accurate – making the character exactly 6 1/4 feet tall. Thus a pixel is 32768 inches x 32768 inches, making it 51.7% of a mile (832.3072 meters) on each side. Finally “map pixels” are split into 256 unit sub-tiles – meaning each pixel has 128×128, 256×256 unit subtiles – each being 21 1/3 feet on each size. When outside, these sub-tiles are the terrain chunks.
Daggerfall uses an interesting way to determine which locations are near the player. Given the world space coordinates of the player (X and Z), the map coordinates can be calculated as follows:
const int maxWorldSpaceZCoord = 16384000; mapPosX = playerObj->xPosition / 32768; mapPosZ = (maxWorldSpaceZCoord - playerObj->zPosition) / 32768;
Then, given the position on the map, an index is computed:
const int mapWidth = 1000; mapIndex = mapPosZ * mapWidth + mapPosX;
This index corresponds directly to the location ID’s. In other words the location ID is actually it’s map position encoded as shown above. This also means that its map position could also be derived directly from its ID.
Note the code was taken from reverse engineered functions, I just decided to show code snippets this time for brevity. Also Daggerfall used shifts instead of divides, but the divides make the code much clearer for the purpose of showing here.