summaryrefslogtreecommitdiff
path: root/src/layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/layer.cpp')
-rw-r--r--src/layer.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/layer.cpp b/src/layer.cpp
new file mode 100644
index 000000000..b897c45a3
--- /dev/null
+++ b/src/layer.cpp
@@ -0,0 +1,137 @@
+/* $Id: map.cpp 23740 2012-01-03 21:32:51Z $ */
+/*
+
+Это модуль, для возможности полноценной игры в трех измерениях
+(подземелье, метро, итп.)
+
+
+Плоское игровое поле выглядит примерно так:
+*-----------*
+| |
+| |
+| |
+*-----------*
+
+Мысленно нарежем его на одинаковые части:
+*---*---*---*
+| | | |
+| | | |
+| | | |
+*---*---*---*
+
+Мысленно соберем части в вертикальную стопочку:
+*---*
+| *---*
+| | *---*
+| | | |
+* | | |
+ * | |
+ *---*
+
+Таким образом имея плоскую карту мы описываем 3д пространство.
+
+Для простоты вся карта делится только по оси Y (разрезы параллельны оси X)
+Деление происходит на 1, 2, 4, или 8 кусочков.
+
+Например было выбрано поле 64х64, с 4-мя слоями:
+Создается карта 64х256, подразумевается, что:
+
+ X Y
+ верхний слой 0--63 0--63
+ второй слой 0--63 64--127
+ третий слой 0--63 128--191
+ четвертый слой 0--63 192--255
+
+
+Обычная карта
+ MapSizeX х (MapSizeY)
+
+Представление в виде слоев
+ LayerSizeX x (LayerSizeY x LayerCount)
+
+Иными словами игровые координаты "плоского" пространства
+
+ MapX, MapY, MapZ
+
+переходят в координаты нового "3д" пространства
+
+ // Константы
+ LayerCount = число кусочков... (1, или 2, или 4, итд.)
+ LayerSizeZ = сдвиг слоя по вертикали (например 1)
+
+ // Аксиомы
+ MapSizeX == LayerSizeX
+ MapSizeY == LayerSizeY * LayerCount
+
+ // Расчет координат
+ LayerIndex = MapY / LayerSizeY
+
+ WorldX = MapX
+ WorldY = MapY - LayerIndex*LayerSizeY
+ WorldZ = MapZ + LayerIndex*LayerSizeZ
+*/
+
+/** @file map.cpp Base functions related to the map and distances on them. */
+
+#include "stdafx.h"
+#include "debug.h"
+#include "core/alloc_func.hpp"
+#include "void_map.h"
+#include "layer_func.h"
+#include "layer_type.h"
+#include "landscape.h"
+
+#if defined(_MSC_VER)
+/* Why the hell is that not in all MSVC headers?? */
+extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned);
+#endif
+
+uint _layer_size_x; ///< Size of the map along the X
+uint _layer_size_y; ///< Size of the map along the Y
+uint _layer_count; ///< The number of tiles on the map
+uint _layer_count_log;
+uint _layer_size; ///< Layer size (sizeX * sizeY)
+
+void InstallLayerSystem(uint size_x, uint size_y, uint layer_count)
+{
+ if (!IsInsideMM(layer_count, MIN_LAYER_COUNT, MAX_LAYER_COUNT))
+ error("invalid layer count");
+
+ _layer_size_x = size_x;
+ _layer_size_y = size_y;
+ _layer_size = size_x * size_y;
+ _layer_count = layer_count;
+ _layer_count_log = FindFirstBit(layer_count);
+}
+
+void FixUndergroundHeights()
+{
+ uint width = MapSizeX();
+ uint height = MapSizeY();
+
+ /* Layer correct */
+ for (uint row = 0; (uint)row < height; row++) {
+
+ /* Граница между слоями */
+ if (!(row % LayerSizeY()))
+ for (uint x = 0; x < width; x++) MakeVoid(width * row + x);
+
+ for (uint col = 0; (uint)col < width; col++) {
+ uint tile = TileXY(row, col);
+ if (IsUnderground(tile))
+ SetTileHeight(tile, 0);
+ }
+ }
+}
+
+uint8 calculateLayer(const ViewPort *vp)
+{
+ // Функция ViewportDoDraw вызывается несколько раз с разными параметрами
+ // Нужно же найти только один слой.
+ // Опираемся на вьюпорт.
+
+ Point pt = InverseRemapCoords(vp->virtual_left+(vp->virtual_width >> 1),vp->virtual_top+(vp->virtual_height >> 1));
+ TileIndex center = TileVirtXY(pt.x, pt.y);
+ return LayerIndex(center);
+}
+