src/viewport.cpp
changeset 8953 fea4aa214d9c
parent 8952 be6bfd75e554
child 8957 ef3f499ff423
equal deleted inserted replaced
8952:be6bfd75e554 8953:fea4aa214d9c
   151 	FoundationPart foundation_part;                  ///< Currently active foundation for ground sprite drawing.
   151 	FoundationPart foundation_part;                  ///< Currently active foundation for ground sprite drawing.
   152 	int *last_foundation_child[FOUNDATION_PART_END]; ///< Tail of ChildSprite list of the foundations. (index into child_screen_sprites_to_draw)
   152 	int *last_foundation_child[FOUNDATION_PART_END]; ///< Tail of ChildSprite list of the foundations. (index into child_screen_sprites_to_draw)
   153 	Point foundation_offset[FOUNDATION_PART_END];    ///< Pixeloffset for ground sprites on the foundations.
   153 	Point foundation_offset[FOUNDATION_PART_END];    ///< Pixeloffset for ground sprites on the foundations.
   154 };
   154 };
   155 
   155 
   156 static ViewportDrawer *_cur_vd;
   156 static ViewportDrawer _vd;
   157 
   157 
   158 TileHighlightData _thd;
   158 TileHighlightData _thd;
   159 static TileInfo *_cur_ti;
   159 static TileInfo *_cur_ti;
   160 
   160 
   161 extern void SmallMapCenterOnCurrentPos(Window *w);
   161 extern void SmallMapCenterOnCurrentPos(Window *w);
   475  */
   475  */
   476 void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub)
   476 void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z, const SubSprite *sub)
   477 {
   477 {
   478 	assert((image & SPRITE_MASK) < MAX_SPRITES);
   478 	assert((image & SPRITE_MASK) < MAX_SPRITES);
   479 
   479 
   480 	TileSpriteToDraw *ts = _cur_vd->tile_sprites_to_draw.Append();
   480 	TileSpriteToDraw *ts = _vd.tile_sprites_to_draw.Append();
   481 	ts->image = image;
   481 	ts->image = image;
   482 	ts->pal = pal;
   482 	ts->pal = pal;
   483 	ts->sub = sub;
   483 	ts->sub = sub;
   484 	ts->x = x;
   484 	ts->x = x;
   485 	ts->y = y;
   485 	ts->y = y;
   498  * @param extra_offs_x Pixel X offset for the sprite position.
   498  * @param extra_offs_x Pixel X offset for the sprite position.
   499  * @param extra_offs_y Pixel Y offset for the sprite position.
   499  * @param extra_offs_y Pixel Y offset for the sprite position.
   500  */
   500  */
   501 static void AddChildSpriteToFoundation(SpriteID image, SpriteID pal, const SubSprite *sub, FoundationPart foundation_part, int extra_offs_x, int extra_offs_y)
   501 static void AddChildSpriteToFoundation(SpriteID image, SpriteID pal, const SubSprite *sub, FoundationPart foundation_part, int extra_offs_x, int extra_offs_y)
   502 {
   502 {
   503 	ViewportDrawer *vd = _cur_vd;
       
   504 	assert(IsInsideMM(foundation_part, 0, FOUNDATION_PART_END));
   503 	assert(IsInsideMM(foundation_part, 0, FOUNDATION_PART_END));
   505 	assert(vd->foundation[foundation_part] != -1);
   504 	assert(_vd.foundation[foundation_part] != -1);
   506 	Point offs = vd->foundation_offset[foundation_part];
   505 	Point offs = _vd.foundation_offset[foundation_part];
   507 
   506 
   508 	/* Change the active ChildSprite list to the one of the foundation */
   507 	/* Change the active ChildSprite list to the one of the foundation */
   509 	int *old_child = vd->last_child;
   508 	int *old_child = _vd.last_child;
   510 	vd->last_child = vd->last_foundation_child[foundation_part];
   509 	_vd.last_child = _vd.last_foundation_child[foundation_part];
   511 
   510 
   512 	AddChildSpriteScreen(image, pal, offs.x + extra_offs_x, offs.y + extra_offs_y, false, sub);
   511 	AddChildSpriteScreen(image, pal, offs.x + extra_offs_x, offs.y + extra_offs_y, false, sub);
   513 
   512 
   514 	/* Switch back to last ChildSprite list */
   513 	/* Switch back to last ChildSprite list */
   515 	vd->last_child = old_child;
   514 	_vd.last_child = old_child;
   516 }
   515 }
   517 
   516 
   518 /**
   517 /**
   519  * Draws a ground sprite for the current tile.
   518  * Draws a ground sprite for the current tile.
   520  * If the current tile is drawn on top of a foundation the sprite is added as child sprite to the "foundation"-ParentSprite.
   519  * If the current tile is drawn on top of a foundation the sprite is added as child sprite to the "foundation"-ParentSprite.
   523  * @param pal the provided palette.
   522  * @param pal the provided palette.
   524  * @param sub Only draw a part of the sprite.
   523  * @param sub Only draw a part of the sprite.
   525  */
   524  */
   526 void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub)
   525 void DrawGroundSprite(SpriteID image, SpriteID pal, const SubSprite *sub)
   527 {
   526 {
   528 	ViewportDrawer *vd = _cur_vd;
       
   529 	/* Switch to first foundation part, if no foundation was drawn */
   527 	/* Switch to first foundation part, if no foundation was drawn */
   530 	if (vd->foundation_part == FOUNDATION_PART_NONE) vd->foundation_part = FOUNDATION_PART_NORMAL;
   528 	if (_vd.foundation_part == FOUNDATION_PART_NONE) _vd.foundation_part = FOUNDATION_PART_NORMAL;
   531 
   529 
   532 	if (vd->foundation[vd->foundation_part] != -1) {
   530 	if (_vd.foundation[_vd.foundation_part] != -1) {
   533 		AddChildSpriteToFoundation(image, pal, sub, vd->foundation_part, 0, 0);
   531 		AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, 0, 0);
   534 	} else {
   532 	} else {
   535 		DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z, sub);
   533 		DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z, sub);
   536 	}
   534 	}
   537 }
   535 }
   538 
   536 
   544  * @param x sprite x-offset (screen coordinates) of ground sprites relative to the "foundation"-ParentSprite.
   542  * @param x sprite x-offset (screen coordinates) of ground sprites relative to the "foundation"-ParentSprite.
   545  * @param y sprite y-offset (screen coordinates) of ground sprites relative to the "foundation"-ParentSprite.
   543  * @param y sprite y-offset (screen coordinates) of ground sprites relative to the "foundation"-ParentSprite.
   546  */
   544  */
   547 void OffsetGroundSprite(int x, int y)
   545 void OffsetGroundSprite(int x, int y)
   548 {
   546 {
   549 	ViewportDrawer *vd = _cur_vd;
       
   550 	/* Switch to next foundation part */
   547 	/* Switch to next foundation part */
   551 	switch (vd->foundation_part) {
   548 	switch (_vd.foundation_part) {
   552 		case FOUNDATION_PART_NONE:
   549 		case FOUNDATION_PART_NONE:
   553 			vd->foundation_part = FOUNDATION_PART_NORMAL;
   550 			_vd.foundation_part = FOUNDATION_PART_NORMAL;
   554 			break;
   551 			break;
   555 		case FOUNDATION_PART_NORMAL:
   552 		case FOUNDATION_PART_NORMAL:
   556 			vd->foundation_part = FOUNDATION_PART_HALFTILE;
   553 			_vd.foundation_part = FOUNDATION_PART_HALFTILE;
   557 			break;
   554 			break;
   558 		default: NOT_REACHED();
   555 		default: NOT_REACHED();
   559 	}
   556 	}
   560 
   557 
   561 	/* vd->last_child == NULL if foundation sprite was clipped by the viewport bounds */
   558 	/* _vd.last_child == NULL if foundation sprite was clipped by the viewport bounds */
   562 	if (vd->last_child != NULL) vd->foundation[vd->foundation_part] = vd->parent_sprites_to_draw.items - 1;
   559 	if (_vd.last_child != NULL) _vd.foundation[_vd.foundation_part] = _vd.parent_sprites_to_draw.items - 1;
   563 
   560 
   564 	vd->foundation_offset[vd->foundation_part].x = x;
   561 	_vd.foundation_offset[_vd.foundation_part].x = x;
   565 	vd->foundation_offset[vd->foundation_part].y = y;
   562 	_vd.foundation_offset[_vd.foundation_part].y = y;
   566 	vd->last_foundation_child[vd->foundation_part] = vd->last_child;
   563 	_vd.last_foundation_child[_vd.foundation_part] = _vd.last_child;
   567 }
   564 }
   568 
   565 
   569 /**
   566 /**
   570  * Adds a child sprite to a parent sprite.
   567  * Adds a child sprite to a parent sprite.
   571  * In contrast to "AddChildSpriteScreen()" the sprite position is in world coordinates
   568  * In contrast to "AddChildSpriteScreen()" the sprite position is in world coordinates
   577  * @param z position z of the sprite.
   574  * @param z position z of the sprite.
   578  * @param sub Only draw a part of the sprite.
   575  * @param sub Only draw a part of the sprite.
   579  */
   576  */
   580 static void AddCombinedSprite(SpriteID image, SpriteID pal, int x, int y, byte z, const SubSprite *sub)
   577 static void AddCombinedSprite(SpriteID image, SpriteID pal, int x, int y, byte z, const SubSprite *sub)
   581 {
   578 {
   582 	const ViewportDrawer *vd = _cur_vd;
       
   583 	Point pt = RemapCoords(x, y, z);
   579 	Point pt = RemapCoords(x, y, z);
   584 	const Sprite* spr = GetSprite(image & SPRITE_MASK);
   580 	const Sprite* spr = GetSprite(image & SPRITE_MASK);
   585 
   581 
   586 	if (pt.x + spr->x_offs >= vd->dpi.left + vd->dpi.width ||
   582 	if (pt.x + spr->x_offs >= _vd.dpi.left + _vd.dpi.width ||
   587 			pt.x + spr->x_offs + spr->width <= vd->dpi.left ||
   583 			pt.x + spr->x_offs + spr->width <= _vd.dpi.left ||
   588 			pt.y + spr->y_offs >= vd->dpi.top + vd->dpi.height ||
   584 			pt.y + spr->y_offs >= _vd.dpi.top + _vd.dpi.height ||
   589 			pt.y + spr->y_offs + spr->height <= vd->dpi.top)
   585 			pt.y + spr->y_offs + spr->height <= _vd.dpi.top)
   590 		return;
   586 		return;
   591 
   587 
   592 	const ParentSpriteToDraw *pstd = vd->parent_sprites_to_draw.End() - 1;
   588 	const ParentSpriteToDraw *pstd = _vd.parent_sprites_to_draw.End() - 1;
   593 	AddChildSpriteScreen(image, pal, pt.x - pstd->left, pt.y - pstd->top, false, sub);
   589 	AddChildSpriteScreen(image, pal, pt.x - pstd->left, pt.y - pstd->top, false, sub);
   594 }
   590 }
   595 
   591 
   596 /** Draw a (transparent) sprite at given coordinates with a given bounding box.
   592 /** Draw a (transparent) sprite at given coordinates with a given bounding box.
   597  * The bounding box extends from (x + bb_offset_x, y + bb_offset_y, z + bb_offset_z) to (x + w - 1, y + h - 1, z + dz - 1), both corners included.
   593  * The bounding box extends from (x + bb_offset_x, y + bb_offset_y, z + bb_offset_z) to (x + w - 1, y + h - 1, z + dz - 1), both corners included.
   617  * @param bb_offset_z bounding box extent towards negative Z (world)
   613  * @param bb_offset_z bounding box extent towards negative Z (world)
   618  * @param sub Only draw a part of the sprite.
   614  * @param sub Only draw a part of the sprite.
   619  */
   615  */
   620 void AddSortableSpriteToDraw(SpriteID image, SpriteID 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)
   616 void AddSortableSpriteToDraw(SpriteID image, SpriteID 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)
   621 {
   617 {
   622 	ViewportDrawer *vd = _cur_vd;
       
   623 	int32 left, right, top, bottom;
   618 	int32 left, right, top, bottom;
   624 
   619 
   625 	assert((image & SPRITE_MASK) < MAX_SPRITES);
   620 	assert((image & SPRITE_MASK) < MAX_SPRITES);
   626 
   621 
   627 	/* make the sprites transparent with the right palette */
   622 	/* make the sprites transparent with the right palette */
   628 	if (transparent) {
   623 	if (transparent) {
   629 		SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
   624 		SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
   630 		pal = PALETTE_TO_TRANSPARENT;
   625 		pal = PALETTE_TO_TRANSPARENT;
   631 	}
   626 	}
   632 
   627 
   633 	if (vd->combine_sprites == 2) {
   628 	if (_vd.combine_sprites == 2) {
   634 		AddCombinedSprite(image, pal, x, y, z, sub);
   629 		AddCombinedSprite(image, pal, x, y, z, sub);
   635 		return;
   630 		return;
   636 	}
   631 	}
   637 
   632 
   638 	vd->last_child = NULL;
   633 	_vd.last_child = NULL;
   639 
   634 
   640 	Point pt = RemapCoords(x, y, z);
   635 	Point pt = RemapCoords(x, y, z);
   641 	int tmp_left, tmp_top, tmp_x = pt.x, tmp_y = pt.y;
   636 	int tmp_left, tmp_top, tmp_x = pt.x, tmp_y = pt.y;
   642 
   637 
   643 	/* Compute screen extents of sprite */
   638 	/* Compute screen extents of sprite */
   661 		top    = min(top   , RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz         ).y);
   656 		top    = min(top   , RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz         ).y);
   662 		bottom = max(bottom, RemapCoords(x + w          , y + h          , z + bb_offset_z).y + 1);
   657 		bottom = max(bottom, RemapCoords(x + w          , y + h          , z + bb_offset_z).y + 1);
   663 	}
   658 	}
   664 
   659 
   665 	/* Do not add the sprite to the viewport, if it is outside */
   660 	/* Do not add the sprite to the viewport, if it is outside */
   666 	if (left   >= vd->dpi.left + vd->dpi.width ||
   661 	if (left   >= _vd.dpi.left + _vd.dpi.width ||
   667 	    right  <= vd->dpi.left                 ||
   662 	    right  <= _vd.dpi.left                 ||
   668 	    top    >= vd->dpi.top + vd->dpi.height ||
   663 	    top    >= _vd.dpi.top + _vd.dpi.height ||
   669 	    bottom <= vd->dpi.top) {
   664 	    bottom <= _vd.dpi.top) {
   670 		return;
   665 		return;
   671 	}
   666 	}
   672 
   667 
   673 	ParentSpriteToDraw *ps = vd->parent_sprites_to_draw.Append();
   668 	ParentSpriteToDraw *ps = _vd.parent_sprites_to_draw.Append();
   674 	ps->x = tmp_x;
   669 	ps->x = tmp_x;
   675 	ps->y = tmp_y;
   670 	ps->y = tmp_y;
   676 
   671 
   677 	ps->left = tmp_left;
   672 	ps->left = tmp_left;
   678 	ps->top  = tmp_top;
   673 	ps->top  = tmp_top;
   688 
   683 
   689 	ps->zmin = z + bb_offset_z;
   684 	ps->zmin = z + bb_offset_z;
   690 	ps->zmax = z + max(bb_offset_z, dz) - 1;
   685 	ps->zmax = z + max(bb_offset_z, dz) - 1;
   691 
   686 
   692 	ps->comparison_done = false;
   687 	ps->comparison_done = false;
   693 	ps->first_child = vd->child_screen_sprites_to_draw.items;
   688 	ps->first_child = _vd.child_screen_sprites_to_draw.items;
   694 	ps->last_child  = vd->child_screen_sprites_to_draw.items;
   689 	ps->last_child  = _vd.child_screen_sprites_to_draw.items;
   695 
   690 
   696 	vd->last_child = &ps->last_child;
   691 	_vd.last_child = &ps->last_child;
   697 
   692 
   698 	if (vd->combine_sprites == 1) vd->combine_sprites = 2;
   693 	if (_vd.combine_sprites == 1) _vd.combine_sprites = 2;
   699 }
   694 }
   700 
   695 
   701 void StartSpriteCombine()
   696 void StartSpriteCombine()
   702 {
   697 {
   703 	_cur_vd->combine_sprites = 1;
   698 	_vd.combine_sprites = 1;
   704 }
   699 }
   705 
   700 
   706 void EndSpriteCombine()
   701 void EndSpriteCombine()
   707 {
   702 {
   708 	_cur_vd->combine_sprites = 0;
   703 	_vd.combine_sprites = 0;
   709 }
   704 }
   710 
   705 
   711 /**
   706 /**
   712  * Add a child sprite to a parent sprite.
   707  * Add a child sprite to a parent sprite.
   713  *
   708  *
   718  * @param transparent if true, switch the palette between the provided palette and the transparent palette,
   713  * @param transparent if true, switch the palette between the provided palette and the transparent palette,
   719  * @param sub Only draw a part of the sprite.
   714  * @param sub Only draw a part of the sprite.
   720  */
   715  */
   721 void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool transparent, const SubSprite *sub)
   716 void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y, bool transparent, const SubSprite *sub)
   722 {
   717 {
   723 	ViewportDrawer *vd = _cur_vd;
       
   724 
       
   725 	assert((image & SPRITE_MASK) < MAX_SPRITES);
   718 	assert((image & SPRITE_MASK) < MAX_SPRITES);
   726 
   719 
   727 	/* If the ParentSprite was clipped by the viewport bounds, do not draw the ChildSprites either */
   720 	/* If the ParentSprite was clipped by the viewport bounds, do not draw the ChildSprites either */
   728 	if (vd->last_child == NULL) return;
   721 	if (_vd.last_child == NULL) return;
   729 
   722 
   730 	/* make the sprites transparent with the right palette */
   723 	/* make the sprites transparent with the right palette */
   731 	if (transparent) {
   724 	if (transparent) {
   732 		SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
   725 		SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
   733 		pal = PALETTE_TO_TRANSPARENT;
   726 		pal = PALETTE_TO_TRANSPARENT;
   734 	}
   727 	}
   735 
   728 
   736 	/* Append the sprite to the active ChildSprite list.
   729 	/* Append the sprite to the active ChildSprite list.
   737 	 * If the active ParentSprite is a foundation, update last_foundation_child as well. */
   730 	 * If the active ParentSprite is a foundation, update last_foundation_child as well. */
   738 	ChildScreenSpriteToDraw *cs = vd->child_screen_sprites_to_draw.Append();
   731 	ChildScreenSpriteToDraw *cs = _vd.child_screen_sprites_to_draw.Append();
   739 	cs->image = image;
   732 	cs->image = image;
   740 	cs->pal = pal;
   733 	cs->pal = pal;
   741 	cs->sub = sub;
   734 	cs->sub = sub;
   742 	cs->x = x;
   735 	cs->x = x;
   743 	cs->y = y;
   736 	cs->y = y;
   744 	cs->next = NULL;
   737 	cs->next = NULL;
   745 
   738 
   746 	*vd->last_child = vd->child_screen_sprites_to_draw.items;
   739 	*_vd.last_child = _vd.child_screen_sprites_to_draw.items;
   747 }
   740 }
   748 
   741 
   749 /* Returns a StringSpriteToDraw */
   742 /* Returns a StringSpriteToDraw */
   750 void AddStringToDraw(int x, int y, StringID string, uint64 params_1, uint64 params_2, uint16 color, uint16 width)
   743 void AddStringToDraw(int x, int y, StringID string, uint64 params_1, uint64 params_2, uint16 color, uint16 width)
   751 {
   744 {
   752 	StringSpriteToDraw *ss = _cur_vd->string_sprites_to_draw.Append();
   745 	StringSpriteToDraw *ss = _vd.string_sprites_to_draw.Append();
   753 	ss->string = string;
   746 	ss->string = string;
   754 	ss->x = x;
   747 	ss->x = x;
   755 	ss->y = y;
   748 	ss->y = y;
   756 	ss->params[0] = params_1;
   749 	ss->params[0] = params_1;
   757 	ss->params[1] = params_2;
   750 	ss->params[1] = params_2;
   772  * @param foundation_part Foundation part the sprite belongs to.
   765  * @param foundation_part Foundation part the sprite belongs to.
   773  */
   766  */
   774 static void DrawSelectionSprite(SpriteID image, SpriteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part)
   767 static void DrawSelectionSprite(SpriteID image, SpriteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part)
   775 {
   768 {
   776 	/* FIXME: This is not totally valid for some autorail highlights, that extent over the edges of the tile. */
   769 	/* FIXME: This is not totally valid for some autorail highlights, that extent over the edges of the tile. */
   777 	if (_cur_vd->foundation[foundation_part] == -1) {
   770 	if (_vd.foundation[foundation_part] == -1) {
   778 		/* draw on real ground */
   771 		/* draw on real ground */
   779 		DrawGroundSpriteAt(image, pal, ti->x, ti->y, ti->z + z_offset);
   772 		DrawGroundSpriteAt(image, pal, ti->x, ti->y, ti->z + z_offset);
   780 	} else {
   773 	} else {
   781 		/* draw on top of foundation */
   774 		/* draw on top of foundation */
   782 		AddChildSpriteToFoundation(image, pal, NULL, foundation_part, 0, -z_offset);
   775 		AddChildSpriteToFoundation(image, pal, NULL, foundation_part, 0, -z_offset);
   945 	}
   938 	}
   946 }
   939 }
   947 
   940 
   948 static void ViewportAddLandscape()
   941 static void ViewportAddLandscape()
   949 {
   942 {
   950 	ViewportDrawer *vd = _cur_vd;
       
   951 	int x, y, width, height;
   943 	int x, y, width, height;
   952 	TileInfo ti;
   944 	TileInfo ti;
   953 	bool direction;
   945 	bool direction;
   954 
   946 
   955 	_cur_ti = &ti;
   947 	_cur_ti = &ti;
   956 
   948 
   957 	/* Transform into tile coordinates and round to closest full tile */
   949 	/* Transform into tile coordinates and round to closest full tile */
   958 	x = ((vd->dpi.top >> 1) - (vd->dpi.left >> 2)) & ~0xF;
   950 	x = ((_vd.dpi.top >> 1) - (_vd.dpi.left >> 2)) & ~0xF;
   959 	y = ((vd->dpi.top >> 1) + (vd->dpi.left >> 2) - 0x10) & ~0xF;
   951 	y = ((_vd.dpi.top >> 1) + (_vd.dpi.left >> 2) - 0x10) & ~0xF;
   960 
   952 
   961 	/* determine size of area */
   953 	/* determine size of area */
   962 	{
   954 	{
   963 		Point pt = RemapCoords(x, y, 241);
   955 		Point pt = RemapCoords(x, y, 241);
   964 		width = (vd->dpi.left + vd->dpi.width - pt.x + 95) >> 6;
   956 		width = (_vd.dpi.left + _vd.dpi.width - pt.x + 95) >> 6;
   965 		height = (vd->dpi.top + vd->dpi.height - pt.y) >> 5 << 1;
   957 		height = (_vd.dpi.top + _vd.dpi.height - pt.y) >> 5 << 1;
   966 	}
   958 	}
   967 
   959 
   968 	assert(width > 0);
   960 	assert(width > 0);
   969 	assert(height > 0);
   961 	assert(height > 0);
   970 
   962 
   995 			}
   987 			}
   996 
   988 
   997 			y_cur += 0x10;
   989 			y_cur += 0x10;
   998 			x_cur -= 0x10;
   990 			x_cur -= 0x10;
   999 
   991 
  1000 			vd->foundation_part = FOUNDATION_PART_NONE;
   992 			_vd.foundation_part = FOUNDATION_PART_NONE;
  1001 			vd->foundation[0] = -1;
   993 			_vd.foundation[0] = -1;
  1002 			vd->foundation[1] = -1;
   994 			_vd.foundation[1] = -1;
  1003 			vd->last_foundation_child[0] = NULL;
   995 			_vd.last_foundation_child[0] = NULL;
  1004 			vd->last_foundation_child[1] = NULL;
   996 			_vd.last_foundation_child[1] = NULL;
  1005 
   997 
  1006 			_tile_type_procs[tt]->draw_tile_proc(&ti);
   998 			_tile_type_procs[tt]->draw_tile_proc(&ti);
  1007 			DrawTileSelection(&ti);
   999 			DrawTileSelection(&ti);
  1008 		} while (--width_cur);
  1000 		} while (--width_cur);
  1009 
  1001 
  1459 	}
  1451 	}
  1460 }
  1452 }
  1461 
  1453 
  1462 void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom)
  1454 void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom)
  1463 {
  1455 {
  1464 	ViewportDrawer vd;
  1456 	DrawPixelInfo *old_dpi = _cur_dpi;
  1465 	int mask;
  1457 	_cur_dpi = &_vd.dpi;
  1466 	int x;
  1458 
  1467 	int y;
  1459 	_vd.dpi.zoom = vp->zoom;
  1468 	DrawPixelInfo *old_dpi;
  1460 	int mask = ScaleByZoom(-1, vp->zoom);
  1469 
  1461 
  1470 	_cur_vd = &vd;
  1462 	_vd.combine_sprites = 0;
  1471 
  1463 
  1472 	old_dpi = _cur_dpi;
  1464 	_vd.dpi.width = (right - left) & mask;
  1473 	_cur_dpi = &vd.dpi;
  1465 	_vd.dpi.height = (bottom - top) & mask;
  1474 
  1466 	_vd.dpi.left = left & mask;
  1475 	vd.dpi.zoom = vp->zoom;
  1467 	_vd.dpi.top = top & mask;
  1476 	mask = ScaleByZoom(-1, vp->zoom);
  1468 	_vd.dpi.pitch = old_dpi->pitch;
  1477 
  1469 	_vd.last_child = NULL;
  1478 	vd.combine_sprites = 0;
  1470 
  1479 
  1471 	int x = UnScaleByZoom(_vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left;
  1480 	vd.dpi.width = (right - left) & mask;
  1472 	int y = UnScaleByZoom(_vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top;
  1481 	vd.dpi.height = (bottom - top) & mask;
  1473 
  1482 	vd.dpi.left = left & mask;
  1474 	_vd.dpi.dst_ptr = BlitterFactoryBase::GetCurrentBlitter()->MoveTo(old_dpi->dst_ptr, x - old_dpi->left, y - old_dpi->top);
  1483 	vd.dpi.top = top & mask;
       
  1484 	vd.dpi.pitch = old_dpi->pitch;
       
  1485 	vd.last_child = NULL;
       
  1486 
       
  1487 	x = UnScaleByZoom(vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left;
       
  1488 	y = UnScaleByZoom(vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top;
       
  1489 
       
  1490 	vd.dpi.dst_ptr = BlitterFactoryBase::GetCurrentBlitter()->MoveTo(old_dpi->dst_ptr, x - old_dpi->left, y - old_dpi->top);
       
  1491 
  1475 
  1492 	ViewportAddLandscape();
  1476 	ViewportAddLandscape();
  1493 	ViewportAddVehicles(&vd.dpi);
  1477 	ViewportAddVehicles(&_vd.dpi);
  1494 	DrawTextEffects(&vd.dpi);
  1478 	DrawTextEffects(&_vd.dpi);
  1495 
  1479 
  1496 	ViewportAddTownNames(&vd.dpi);
  1480 	ViewportAddTownNames(&_vd.dpi);
  1497 	ViewportAddStationNames(&vd.dpi);
  1481 	ViewportAddStationNames(&_vd.dpi);
  1498 	ViewportAddSigns(&vd.dpi);
  1482 	ViewportAddSigns(&_vd.dpi);
  1499 	ViewportAddWaypoints(&vd.dpi);
  1483 	ViewportAddWaypoints(&_vd.dpi);
  1500 
  1484 
  1501 	if (vd.tile_sprites_to_draw.items != 0) ViewportDrawTileSprites(&vd.tile_sprites_to_draw);
  1485 	if (_vd.tile_sprites_to_draw.items != 0) ViewportDrawTileSprites(&_vd.tile_sprites_to_draw);
  1502 
  1486 
  1503 	for (ParentSpriteToDraw *it = vd.parent_sprites_to_draw.Begin(); it != vd.parent_sprites_to_draw.End(); it++) {
  1487 	ParentSpriteToDraw *psd_end = _vd.parent_sprites_to_draw.End();
  1504 		*vd.parent_sprites_to_sort.Append() = it;
  1488 	for (ParentSpriteToDraw *it = _vd.parent_sprites_to_draw.Begin(); it != psd_end; it++) {
  1505 	}
  1489 		*_vd.parent_sprites_to_sort.Append() = it;
  1506 
  1490 	}
  1507 	ViewportSortParentSprites(&vd.parent_sprites_to_sort);
  1491 
  1508 	ViewportDrawParentSprites(&vd.parent_sprites_to_sort, &vd.child_screen_sprites_to_draw);
  1492 	ViewportSortParentSprites(&_vd.parent_sprites_to_sort);
  1509 
  1493 	ViewportDrawParentSprites(&_vd.parent_sprites_to_sort, &_vd.child_screen_sprites_to_draw);
  1510 	if (_draw_bounding_boxes) ViewportDrawBoundingBoxes(&vd.parent_sprites_to_sort);
  1494 
  1511 
  1495 	if (_draw_bounding_boxes) ViewportDrawBoundingBoxes(&_vd.parent_sprites_to_sort);
  1512 	if (vd.string_sprites_to_draw.items != 0) ViewportDrawStrings(&vd.dpi, &vd.string_sprites_to_draw);
  1496 
       
  1497 	if (_vd.string_sprites_to_draw.items != 0) ViewportDrawStrings(&_vd.dpi, &_vd.string_sprites_to_draw);
  1513 
  1498 
  1514 	_cur_dpi = old_dpi;
  1499 	_cur_dpi = old_dpi;
       
  1500 
       
  1501 	_vd.string_sprites_to_draw.items = 0;
       
  1502 	_vd.tile_sprites_to_draw.items = 0;
       
  1503 	_vd.parent_sprites_to_draw.items = 0;
       
  1504 	_vd.parent_sprites_to_sort.items = 0;
       
  1505 	_vd.child_screen_sprites_to_draw.items = 0;
  1515 }
  1506 }
  1516 
  1507 
  1517 /** Make sure we don't draw a too big area at a time.
  1508 /** Make sure we don't draw a too big area at a time.
  1518  * If we do, the sprite memory will overflow. */
  1509  * If we do, the sprite memory will overflow. */
  1519 static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom)
  1510 static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom)