90 #include "table/strings.h" 
   95 Point _tile_fract_coords;
 
  178 bool _draw_bounding_boxes = 
false;
 
  179 bool _draw_dirty_blocks = 
false;
 
  180 uint _dirty_block_colour = 0;
 
  183 static Point MapXYZToViewport(
const ViewPort *vp, 
int x, 
int y, 
int z)
 
  191 void DeleteWindowViewport(
Window *w)
 
  213   int width, 
int height, uint32 follow_flags, 
ZoomLevel zoom)
 
  231   if (follow_flags & 0x80000000) {
 
  242     pt = MapXYZToViewport(vp, x, y, GetSlopePixelZ(x, y));
 
  257 static Point _vp_move_offs;
 
  259 static void DoSetViewportPosition(
const Window *w, 
int left, 
int top, 
int width, 
int height)
 
  262     if (left + width > w->
left &&
 
  264         top + height > w->
top &&
 
  267       if (left < w->left) {
 
  268         DoSetViewportPosition(w, left, top, w->
left - left, height);
 
  269         DoSetViewportPosition(w, left + (w->
left - left), top, width - (w->
left - left), height);
 
  274         DoSetViewportPosition(w, left, top, (w->
left + w->
width - left), height);
 
  275         DoSetViewportPosition(w, left + (w->
left + w->
width - left), top, width - (w->
left + w->
width - left), height);
 
  280         DoSetViewportPosition(w, left, top, width, (w->
top - top));
 
  281         DoSetViewportPosition(w, left, top + (w->
top - top), width, height - (w->
top - top));
 
  286         DoSetViewportPosition(w, left, top, width, (w->
top + w->
height - top));
 
  287         DoSetViewportPosition(w, left, top + (w->
top + w->
height - top), width, height - (w->
top + w->
height - top));
 
  296     int xo = _vp_move_offs.x;
 
  297     int yo = _vp_move_offs.y;
 
  299     if (
abs(xo) >= width || 
abs(yo) >= height) {
 
  301       RedrawScreenRect(left, top, left + width, top + height);
 
  305     GfxScroll(left, top, width, height, xo, yo);
 
  308       RedrawScreenRect(left, top, xo + left, top + height);
 
  312       RedrawScreenRect(left + width + xo, top, left + width, top + height);
 
  317       RedrawScreenRect(left, top, width + left, top + yo);
 
  319       RedrawScreenRect(left, top + height + yo, width + left, top + height);
 
  324 static void SetViewportPosition(
Window *w, 
int x, 
int y)
 
  330   int left, top, width, height;
 
  346   if (old_top == 0 && old_left == 0) 
return;
 
  348   _vp_move_offs.x = old_left;
 
  349   _vp_move_offs.y = old_top;
 
  361   i = left + width - _screen.width;
 
  362   if (i >= 0) width -= i;
 
  370     i = top + height - _screen.height;
 
  371     if (i >= 0) height -= i;
 
  373     if (height > 0) DoSetViewportPosition(w->
z_front, left, top, width, height);
 
  411   if ( (uint)(x -= vp->
left) >= (uint)vp->
width ||
 
  412         (uint)(y -= vp->
top) >= (uint)vp->
height) {
 
  430     b = 
Clamp(b, -extra_tiles * TILE_SIZE, 
MapMaxY() * TILE_SIZE - 1);
 
  462 static Point GetTileFromScreenXY(
int x, 
int y, 
int zoom_x, 
int zoom_y)
 
  476 Point GetTileBelowCursor()
 
  478   return GetTileFromScreenXY(_cursor.
pos.x, _cursor.
pos.y, _cursor.
pos.x, _cursor.
pos.y);
 
  488     x = ((_cursor.
pos.x - vp->
left) >> 1) + (vp->
width >> 2);
 
  489     y = ((_cursor.
pos.y - vp->
top) >> 1) + (vp->
height >> 2);
 
  495   return GetTileFromScreenXY(_cursor.
pos.x, _cursor.
pos.y, x + vp->
left, y + vp->
top);
 
  536   ts->
x = pt.x + extra_offs_x;
 
  537   ts->
y = pt.y + extra_offs_y;
 
  554   assert(
IsInsideMM(foundation_part, 0, FOUNDATION_PART_END));
 
  555   assert(_vd.
foundation[foundation_part] != -1);
 
  559   int *old_child = _vd.last_child;
 
  562   AddChildSpriteScreen(image, pal, offs.x + extra_offs_x, offs.y + extra_offs_y, 
false, sub, 
false);
 
  565   _vd.last_child = old_child;
 
  590     AddTileSpriteToDraw(image, pal, _cur_ti->
x + x, _cur_ti->
y + y, _cur_ti->
z + z, sub, extra_offs_x * ZOOM_LVL_BASE, extra_offs_y * ZOOM_LVL_BASE);
 
  626     default: NOT_REACHED();
 
  653   if (pt.x + spr->
x_offs >= _vd.dpi.left + _vd.dpi.width ||
 
  655       pt.y + spr->
y_offs >= _vd.dpi.top + _vd.dpi.height ||
 
  688 void AddSortableSpriteToDraw(
SpriteID image, 
PaletteID pal, 
int x, 
int y, 
int w, 
int h, 
int dz, 
int z, 
bool transparent, 
int bb_offset_x, 
int bb_offset_y, 
int bb_offset_z, 
const SubSprite *sub)
 
  690   int32 left, right, top, bottom;
 
  705   _vd.last_child = NULL;
 
  708   int tmp_left, tmp_top, tmp_x = pt.x, tmp_y = pt.y;
 
  711   if (image == SPR_EMPTY_BOUNDING_BOX) {
 
  712     left = tmp_left = 
RemapCoords(x + w          , y + bb_offset_y, z + bb_offset_z).x;
 
  713     right           = 
RemapCoords(x + bb_offset_x, y + h          , z + bb_offset_z).x + 1;
 
  714     top  = tmp_top  = 
RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz         ).y;
 
  715     bottom          = 
RemapCoords(x + w          , y + h          , z + bb_offset_z).y + 1;
 
  718     left = tmp_left = (pt.x += spr->
x_offs);
 
  719     right           = (pt.x +  spr->
width );
 
  720     top  = tmp_top  = (pt.y += spr->
y_offs);
 
  721     bottom          = (pt.y +  spr->
height);
 
  724   if (_draw_bounding_boxes && (image != SPR_EMPTY_BOUNDING_BOX)) {
 
  726     left   = 
min(left  , 
RemapCoords(x + w          , y + bb_offset_y, z + bb_offset_z).x);
 
  727     right  = 
max(right , 
RemapCoords(x + bb_offset_x, y + h          , z + bb_offset_z).x + 1);
 
  728     top    = 
min(top   , 
RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz         ).y);
 
  729     bottom = 
max(bottom, 
RemapCoords(x + w          , y + h          , z + bb_offset_z).y + 1);
 
  733   if (left   >= _vd.dpi.left + _vd.dpi.width ||
 
  734       right  <= _vd.dpi.left                 ||
 
  735       top    >= _vd.dpi.top + _vd.dpi.height ||
 
  736       bottom <= _vd.dpi.top) {
 
  750   ps->
xmin = x + bb_offset_x;
 
  751   ps->
xmax = x + 
max(bb_offset_x, w) - 1;
 
  753   ps->
ymin = y + bb_offset_y;
 
  754   ps->
ymax = y + 
max(bb_offset_y, h) - 1;
 
  756   ps->
zmin = z + bb_offset_z;
 
  757   ps->
zmax = z + 
max(bb_offset_z, dz) - 1;
 
  812   if (begin > end) 
Swap(begin, end);
 
  813   return begin <= check && check <= end;
 
  824   int dist_a = (_thd.
size.x + _thd.
size.y);      
 
  825   int dist_b = (_thd.
size.x - _thd.
size.y);      
 
  826   int a = ((x - _thd.
pos.x) + (y - _thd.
pos.y)); 
 
  827   int b = ((x - _thd.
pos.x) - (y - _thd.
pos.y));
 
  848   if (_vd.last_child == NULL) 
return;
 
  856   *_vd.last_child = _vd.child_screen_sprites_to_draw.
Length();
 
  862   cs->x = scale ? x * ZOOM_LVL_BASE : x;
 
  863   cs->y = scale ? y * ZOOM_LVL_BASE : y;
 
  871   _vd.last_child = &cs->
next;
 
  874 static void AddStringToDraw(
int x, 
int y, 
StringID string, uint64 params_1, uint64 params_2, Colours colour, uint16 width)
 
  881   ss->params[0] = params_1;
 
  882   ss->params[1] = params_2;
 
  924     SpriteID sel2 = SPR_HALFTILE_SELECTION_FLAT + halftile_corner;
 
  929       sel = SPR_HALFTILE_SELECTION_DOWN;
 
  933     sel += opposite_corner;
 
  940 static bool IsPartOfAutoLine(
int px, 
int py)
 
  950     case HT_DIR_HU: 
return px == -py || px == -py - 16; 
 
  951     case HT_DIR_HL: 
return px == -py || px == -py + 16; 
 
  952     case HT_DIR_VL: 
return px == py || px == py + 16; 
 
  953     case HT_DIR_VR: 
return px == py || px == py - 16; 
 
  986     static const uint _lower_rail[4] = { 5U, 2U, 4U, 3U };
 
  988     if (autorail_type != _lower_rail[halftile_corner]) {
 
  995   offset = _AutorailTilehSprite[autorail_tileh][autorail_type];
 
  997     image = SPR_AUTORAIL_BASE + offset;
 
 1000     image = SPR_AUTORAIL_BASE - offset;
 
 1041         if ((halftile_corner == CORNER_W) || (halftile_corner == CORNER_E)) z += 
TILE_HEIGHT;
 
 1042         if (halftile_corner != CORNER_S) {
 
 1053     } 
else if (IsPartOfAutoLine(ti->
x, ti->
y)) {
 
 1071   if (!is_redsq && _thd.
outersize.x > 0 &&
 
 1097   assert(_vd.dpi.top <= _vd.dpi.top + _vd.dpi.height);
 
 1098   assert(_vd.dpi.left <= _vd.dpi.left + _vd.dpi.width);
 
 1116   int left_column = (upper_left.y - upper_left.x) / (
int)
TILE_SIZE - 2;
 
 1117   int right_column = (upper_right.y - upper_right.x) / (
int)
TILE_SIZE + 2;
 
 1125   int row = (upper_left.x + upper_left.y) / (
int)
TILE_SIZE - 2;
 
 1126   bool last_row = 
false;
 
 1127   for (; !last_row; row++) {
 
 1129     for (
int column = left_column; column <= right_column; column++) {
 
 1131       if ((row + column) % 2 != 0) 
continue;
 
 1134       tilecoord.x = (row - column) / 2;
 
 1135       tilecoord.y = (row + column) / 2;
 
 1136       assert(column == tilecoord.y - tilecoord.x);
 
 1137       assert(row == tilecoord.y + tilecoord.x);
 
 1141       _cur_ti = &tile_info;
 
 1147         tile_info.
tile = 
TileXY(tilecoord.x, tilecoord.y);
 
 1171       int min_visible_height = viewport_y - (_vd.dpi.top + _vd.dpi.height);
 
 1172       bool tile_visible = min_visible_height <= 0;
 
 1191         if ((tilecoord.x <= 0 || tilecoord.y <= 0) && min_visible_height < potential_bridge_height + 
MAX_TILE_EXTENT_TOP) last_row = 
false;
 
 1221   bool small = dpi->zoom >= small_from;
 
 1223   int left   = dpi->left;
 
 1225   int right  = left + dpi->width;
 
 1226   int bottom = top + dpi->height;
 
 1231   if (bottom < sign->top ||
 
 1232       top   > sign->
top + sign_height ||
 
 1233       right < sign->center - sign_half_width ||
 
 1234       left  > sign->
center + sign_half_width) {
 
 1239     AddStringToDraw(sign->
center - sign_half_width, sign->
top, string_normal, params_1, params_2, colour, sign->
width_normal);
 
 1241     int shadow_offset = 0;
 
 1242     if (string_small_shadow != STR_NULL) {
 
 1244       AddStringToDraw(sign->
center - sign_half_width + shadow_offset, sign->
top, string_small_shadow, params_1, params_2, INVALID_COLOUR, sign->
width_small);
 
 1246     AddStringToDraw(sign->
center - sign_half_width, sign->
top - shadow_offset, string_small, params_1, params_2,
 
 1259         STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK,
 
 1270   FOR_ALL_BASE_STATIONS(st) {
 
 1281         is_station ? STR_VIEWPORT_STATION : STR_VIEWPORT_WAYPOINT,
 
 1282         (is_station ? STR_VIEWPORT_STATION : STR_VIEWPORT_WAYPOINT) + 1, STR_NULL,
 
 1322   GetString(buffer, str, 
lastof(buffer));
 
 1327   if (str_small != STR_NULL) {
 
 1328     GetString(buffer, str_small, 
lastof(buffer));
 
 1348     zoomlevels[zoom].top    = this->top    - 
ScaleByZoom(1, zoom);
 
 1354   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1356     if (vp != NULL && vp->
zoom <= maxzoom) {
 
 1357       assert(vp->
width != 0);
 
 1383   while (psd != psdvend) {
 
 1429         *psd3 = *(psd3 - 1);
 
 1444     while (child_idx >= 0) {
 
 1446       child_idx = cs->
next;
 
 1467             pt2.x - pt1.x, pt2.y - pt1.y,
 
 1468             pt3.x - pt1.x, pt3.y - pt1.y,
 
 1469             pt4.x - pt1.x, pt4.y - pt1.y);
 
 1488   byte bo = 
UnScaleByZoom(dpi->left + dpi->top, dpi->zoom) & 1;
 
 1490     for (
int i = (bo ^= 1); i < right; i += 2) blitter->
SetPixel(dst, i, 0, (uint8)colour);
 
 1491     dst = blitter->
MoveTo(dst, 0, 1);
 
 1492   } 
while (--bottom > 0);
 
 1500     bool small = 
HasBit(ss->width, 15);
 
 1501     int w = 
GB(ss->width, 0, 15);
 
 1509     if (ss->colour != INVALID_COLOUR) {
 
 1522           x, y, x + w, y + h, ss->colour,
 
 1532 void ViewportDoDraw(
const ViewPort *vp, 
int left, 
int top, 
int right, 
int bottom)
 
 1535   _cur_dpi = &_vd.dpi;
 
 1537   _vd.dpi.zoom = vp->
zoom;
 
 1542   _vd.dpi.width = (right - left) & mask;
 
 1543   _vd.dpi.height = (bottom - top) & mask;
 
 1544   _vd.dpi.left = left & mask;
 
 1545   _vd.dpi.top = top & mask;
 
 1546   _vd.dpi.pitch = old_dpi->pitch;
 
 1547   _vd.last_child = NULL;
 
 1557   ViewportAddTownNames(&_vd.dpi);
 
 1558   ViewportAddStationNames(&_vd.dpi);
 
 1559   ViewportAddSigns(&_vd.dpi);
 
 1561   DrawTextEffects(&_vd.dpi);
 
 1563   if (_vd.tile_sprites_to_draw.
Length() != 0) ViewportDrawTileSprites(&_vd.tile_sprites_to_draw);
 
 1587     vp->overlay->
Draw(&dp);
 
 1590   if (_vd.string_sprites_to_draw.
Length() != 0) {
 
 1594     ViewportDrawStrings(zoom, &_vd.string_sprites_to_draw);
 
 1599   _vd.string_sprites_to_draw.
Clear();
 
 1600   _vd.tile_sprites_to_draw.
Clear();
 
 1601   _vd.parent_sprites_to_draw.
Clear();
 
 1603   _vd.child_screen_sprites_to_draw.
Clear();
 
 1613     if ((bottom - top) > (right - left)) {
 
 1614       int t = (top + bottom) >> 1;
 
 1618       int t = (left + right) >> 1;
 
 1632 static inline void ViewportDraw(
const ViewPort *vp, 
int left, 
int top, 
int right, 
int bottom)
 
 1634   if (right <= vp->left || bottom <= vp->top) 
return;
 
 1636   if (left >= vp->
left + vp->
width) 
return;
 
 1638   if (left < vp->left) left = vp->
left;
 
 1641   if (top >= vp->
top + vp->
height) 
return;
 
 1643   if (top < vp->top) top = vp->
top;
 
 1656   dpi->left += this->
left;
 
 1657   dpi->top += this->
top;
 
 1659   ViewportDraw(this->
viewport, dpi->left, dpi->top, dpi->left + dpi->width, dpi->top + dpi->height);
 
 1661   dpi->left -= this->
left;
 
 1662   dpi->top -= this->
top;
 
 1697     iter = 
Clamp(iter + offset, 0, iter_limit);
 
 1699   } 
while (continue_criteria(iter, iter_limit, sy, sy_limit));
 
 1718 static inline int ClampXYToMap(
Point &curr_tile, 
int &iter, 
int iter_limit, 
int start, 
int &other_ref, 
int other_value, 
int vp_value, 
int other_limit, 
int vp_top, 
int vp_bottom)
 
 1730   other_ref = upper_edge ? 0 : other_limit;
 
 1737   min_iter = 
min(min_iter, max_iter);
 
 1740   int max_heightlevel_at_edge = 0;
 
 1741   for (iter = min_iter; iter <= max_iter; iter += 10) {
 
 1742     max_heightlevel_at_edge = 
max(max_heightlevel_at_edge, (
int)
TileHeight(
TileXY(curr_tile.x, curr_tile.y)));
 
 1748       max(vp_value, -max_heightlevel_at_edge * (
int)(
TILE_HEIGHT * 2 * ZOOM_LVL_BASE)) :
 
 1752 static inline void ClampViewportToMap(
const ViewPort *vp, 
int &x, 
int &y)
 
 1762   int vx = -x + y * 2;
 
 1767   int tx = vx / (int)(
TILE_SIZE * 4 * ZOOM_LVL_BASE);
 
 1768   int ty = vy / (int)(
TILE_SIZE * 4 * ZOOM_LVL_BASE);
 
 1797     SetViewportPosition(w, pt.x, pt.y);
 
 1805     bool update_overlay = 
false;
 
 1806     if (delta_x != 0 || delta_y != 0) {
 
 1823     if (update_overlay) RebuildViewportOverlay(w);
 
 1839   right  += (1 << vp->
zoom) - 1;
 
 1840   bottom += (1 << vp->
zoom) - 1;
 
 1843   if (right <= 0) 
return;
 
 1846   if (bottom <= 0) 
return;
 
 1875   FOR_ALL_WINDOWS_FROM_BACK(w) {
 
 1878       assert(vp->
width != 0);
 
 1884 void ConstrainAllViewportsZoom()
 
 1887   FOR_ALL_WINDOWS_FROM_FRONT(w) {
 
 1939   int x_size = _thd.
size.x;
 
 1940   int y_size = _thd.
size.y;
 
 1943     int x_start = _thd.
pos.x;
 
 1944     int y_start = _thd.
pos.y;
 
 1948       x_start += _thd.
offs.x;
 
 1950       y_start += _thd.
offs.y;
 
 1956     assert(x_size >= 0);
 
 1957     assert(y_size >= 0);
 
 1966     assert((x_end | y_end | x_start | y_start) % 
TILE_SIZE == 0);
 
 1987     int top_y = y_start;
 
 2008       static const int OVERLAY_WIDTH = 4 * ZOOM_LVL_BASE; 
 
 2014       if (top_x != x_start) {
 
 2021       if (bot_y != y_end) {
 
 2026     } 
while (bot_x >= top_x);
 
 2029     int a_size = x_size + y_size, b_size = x_size - y_size;
 
 2034     for (
int a = -interval_a; a != a_size + interval_a; a += interval_a) {
 
 2035       for (
int b = -interval_b; b != b_size + interval_b; b += interval_b) {
 
 2048 void SetSelectionRed(
bool b)
 
 2071   return y >= sign->
top && y < sign->
top + sign_height &&
 
 2072       x >= sign->
center - sign_half_width && x < sign->
center + sign_half_width;
 
 2075 static bool CheckClickOnTown(
const ViewPort *vp, 
int x, 
int y)
 
 2082       ShowTownViewWindow(t->
index);
 
 2090 static bool CheckClickOnStation(
const ViewPort *vp, 
int x, 
int y)
 
 2095   FOR_ALL_BASE_STATIONS(st) {
 
 2119 static bool CheckClickOnSign(
const ViewPort *vp, 
int x, 
int y)
 
 2128     if (si->owner == 
OWNER_DEITY && _game_mode != GM_EDITOR) 
continue;
 
 2140 static bool CheckClickOnLandscape(
const ViewPort *vp, 
int x, 
int y)
 
 2144   if (pt.x != -1) 
return ClickTile(
TileVirtXY(pt.x, pt.y));
 
 2148 static void PlaceObject()
 
 2153   pt = GetTileBelowCursor();
 
 2154   if (pt.x == -1) 
return;
 
 2169 bool HandleViewportClicked(
const ViewPort *vp, 
int x, 
int y)
 
 2183   if (CheckClickOnTown(vp, x, y)) 
return true;
 
 2184   if (CheckClickOnStation(vp, x, y)) 
return true;
 
 2185   if (CheckClickOnSign(vp, x, y)) 
return true;
 
 2186   bool result = CheckClickOnLandscape(vp, x, y);
 
 2203 void RebuildViewportOverlay(
Window *w)
 
 2205   if (w->
viewport->overlay != NULL &&
 
 2228       z = GetSlopePixelZ(x, y);
 
 2242     RebuildViewportOverlay(w);
 
 2303 void SetTileSelectBigSize(
int ox, 
int oy, 
int sx, 
int sy)
 
 2361   bool new_diagonal = 
false;
 
 2373         new_diagonal = 
true;
 
 2375         if (x1 >= x2) 
Swap(x1, x2);
 
 2376         if (y1 >= y2) 
Swap(y1, y2);
 
 2382       if (!new_diagonal) {
 
 2389     Point pt = GetTileBelowCursor();
 
 2421             default: NOT_REACHED();
 
 2504 void VpSetPlaceSizingLimit(
int limit)
 
 2528 static void VpStartPreSizing()
 
 2540   int fxpy = _tile_fract_coords.x + _tile_fract_coords.y;
 
 2542   int fxmy = _tile_fract_coords.x - _tile_fract_coords.y;
 
 2546     default: NOT_REACHED();
 
 2548       if (fxpy >= 20 && sxpy <= 12) 
return HT_DIR_HL;
 
 2549       if (fxmy < -3 && sxmy > 3) 
return HT_DIR_VR;
 
 2553       if (fxmy > 3 && sxmy < -3) 
return HT_DIR_VL;
 
 2554       if (fxpy <= 12 && sxpy >= 20) 
return HT_DIR_HU;
 
 2558       if (fxmy > 3 && sxmy < -3) 
return HT_DIR_VL;
 
 2559       if (fxpy >= 20 && sxpy <= 12) 
return HT_DIR_HL;
 
 2563       if (fxmy < -3 && sxmy > 3) 
return HT_DIR_VR;
 
 2564       if (fxpy <= 12 && sxpy >= 20) 
return HT_DIR_HU;
 
 2584   uint start_x = 
TileX(start_tile);
 
 2585   uint start_y = 
TileY(start_tile);
 
 2586   uint end_x = 
TileX(end_tile);
 
 2587   uint end_y = 
TileY(end_tile);
 
 2591     case HT_LINE: 
return (end_x > start_x || (end_x == start_x && end_y > start_y));
 
 2594     case HT_POINT: 
return (end_x != start_x && end_y < start_y);
 
 2595     default: NOT_REACHED();
 
 2621   if (start_tile == end_tile) 
return 0;
 
 2622   if (swap) 
Swap(start_tile, end_tile);
 
 2633       byte style_t = (byte)(
TileX(end_tile) > 
TileX(start_tile));
 
 2648          {1, 0}, {1, 1},  {0, 1}, {1, 1}, 
 
 2649          {1, 0}, {0, 0},  {1, 0}, {1, 1}, 
 
 2650          {1, 0}, {1, 1},  {0, 1}, {1, 1}, 
 
 2652          {0, 1}, {0, 0},  {1, 0}, {0, 0}, 
 
 2653          {0, 1}, {0, 0},  {1, 1}, {0, 1}, 
 
 2654          {1, 0}, {0, 0},  {0, 0}, {0, 1}, 
 
 2664       if (swap && distance == 0) style = flip_style_direction[style];
 
 2667       byte style_t = style * 2;
 
 2668       assert(style_t < 
lengthof(heightdiff_line_by_dir) - 13);
 
 2675       if (distance == 0) style_t = flip_style_direction[style] * 2;
 
 2676       assert(style_t < 
lengthof(heightdiff_line_by_dir) - 13);
 
 2684   if (swap) 
Swap(h0, h1);
 
 2688 static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
 
 2698   if (test >= 0) 
return;
 
 2700   other += mult * test;
 
 2713   if (test <= max) 
return;
 
 2715   other += mult * (test - 
max);
 
 2758           int offset = (raw_dx - raw_dy) / 2;
 
 2793           int offset = (raw_dx + raw_dy + (int)
TILE_SIZE) / 2;
 
 2842   } 
else if (w > h * 2) { 
 
 2845   } 
else if (h > w * 2) { 
 
 2859         } 
else if (d >= 0) {
 
 2870         } 
else if (d >= 0) {
 
 2883         } 
else if (d >= 0) {
 
 2894         } 
else if (d >= 0) {
 
 2912     if (distance != 1) {
 
 2918         distance = 
CeilDiv(distance, 2);
 
 2921       params[index++] = distance;
 
 2922       if (heightdiff != 0) params[index++] = heightdiff;
 
 2971       if (
abs(sy - y) < 
abs(sx - x)) {
 
 2978       goto calc_heightdiff_single_direction;
 
 2987       goto calc_heightdiff_single_direction;
 
 2997 calc_heightdiff_single_direction:;
 
 2999         x = sx + 
Clamp(x - sx, -limit, limit);
 
 3000         y = sy + 
Clamp(y - sy, -limit, limit);
 
 3009         if (distance != 1) {
 
 3017           params[index++] = distance;
 
 3018           if (heightdiff != 0) params[index++] = heightdiff;
 
 3027       x = sx + 
Clamp(x - sx, -limit, limit);
 
 3028       y = sy + 
Clamp(y - sy, -limit, limit);
 
 3033         static const StringID measure_strings_area[] = {
 
 3034           STR_NULL, STR_NULL, STR_MEASURE_AREA, STR_MEASURE_AREA_HEIGHTDIFF
 
 3060           int a_max = dist_x + dist_y;
 
 3061           int b_max = dist_y - dist_x;
 
 3065           a_max = 
abs(a_max + (a_max > 0 ? 2 : -2)) / 2;
 
 3066           b_max = 
abs(b_max + (b_max > 0 ? 2 : -2)) / 2;
 
 3072           if (a_max != 1 || b_max != 1) {
 
 3079           } 
else if (dy == 1) {
 
 3084         if (dx != 1 || dy != 1) {
 
 3087           params[index++] = dx - (style & 
HT_POINT ? 1 : 0);
 
 3088           params[index++] = dy - (style & 
HT_POINT ? 1 : 0);
 
 3089           if (heightdiff != 0) params[index++] = heightdiff;
 
 3096     default: NOT_REACHED();
 
 3237   { &ViewportSortParentSpritesSSE41Checker, &ViewportSortParentSpritesSSE41 },
 
 3245   for (uint i = 0; i < 
lengthof(_vp_sprite_sorters); i++) {
 
 3246     if (_vp_sprite_sorters[i].fct_checker()) {
 
 3247       _vp_sprite_sorter = _vp_sprite_sorters[i].
fct_sorter;
 
 3251   assert(_vp_sprite_sorter != NULL);