src/viewport.cpp
changeset 8957 ef3f499ff423
parent 8953 fea4aa214d9c
child 8969 6d1c74e0e2cd
equal deleted inserted replaced
8956:359bcdf14389 8957:ef3f499ff423
     1 /* $Id$ */
     1 /* $Id$ */
     2 
     2 
     3 /** @file viewport.cpp */
     3 /** @file viewport.cpp
       
     4  *
       
     5  * \verbatim
       
     6  * The in-game coordinate system looks like this *
       
     7  *                                               *
       
     8  *                    ^ Z                        *
       
     9  *                    |                          *
       
    10  *                    |                          *
       
    11  *                    |                          *
       
    12  *                    |                          *
       
    13  *                 /     \                       *
       
    14  *              /           \                    *
       
    15  *           /                 \                 *
       
    16  *        /                       \              *
       
    17  *   X <                             > Y         *
       
    18  * \endverbatim
       
    19  */
     4 
    20 
     5 #include "stdafx.h"
    21 #include "stdafx.h"
     6 #include "openttd.h"
    22 #include "openttd.h"
     7 #include "debug.h"
    23 #include "debug.h"
     8 #include "tile_cmd.h"
    24 #include "tile_cmd.h"
    35 
    51 
    36 PlaceProc *_place_proc;
    52 PlaceProc *_place_proc;
    37 Point _tile_fract_coords;
    53 Point _tile_fract_coords;
    38 ZoomLevel _saved_scrollpos_zoom;
    54 ZoomLevel _saved_scrollpos_zoom;
    39 
    55 
    40 /**
       
    41  * The maximum number of viewports depends on the maximum number
       
    42  * of windows. Technically is could be the maximum number of
       
    43  * windows, but there is always at least one window that does
       
    44  * not need a viewport. Not having 'support' for that viewport
       
    45  * saves some time and memory.
       
    46  * For the introduction GUI and create game GUIs there is no
       
    47  * need for more than one viewport, however in the normal game
       
    48  * and scenario editor one can make a lot of viewports. For the
       
    49  * normal game one always has a main toolbar and a status bar,
       
    50  * however the statusbar does not exist on the scenario editor.
       
    51  *
       
    52  * This means that we can only safely assume that there is one
       
    53  * window without viewport.
       
    54  */
       
    55 static ViewPort _viewports[MAX_NUMBER_OF_WINDOWS - 1];
       
    56 static uint32 _active_viewports;    ///< bitmasked variable where each bit signifies if a viewport is in use or not
       
    57 assert_compile(lengthof(_viewports) < sizeof(_active_viewports) * 8);
       
    58 
       
    59 /* The in-game coordiante system looks like this *
       
    60  *                                               *
       
    61  *                    ^ Z                        *
       
    62  *                    |                          *
       
    63  *                    |                          *
       
    64  *                    |                          *
       
    65  *                    |                          *
       
    66  *                 /     \                       *
       
    67  *              /           \                    *
       
    68  *           /                 \                 *
       
    69  *        /                       \              *
       
    70  *   X <                             > Y         *
       
    71  */
       
    72 
       
    73 struct StringSpriteToDraw {
    56 struct StringSpriteToDraw {
    74 	uint16 string;
    57 	uint16 string;
    75 	uint16 color;
    58 	uint16 color;
    76 	int32 x;
    59 	int32 x;
    77 	int32 y;
    60 	int32 y;
   166 	p.x -= vp->virtual_width / 2;
   149 	p.x -= vp->virtual_width / 2;
   167 	p.y -= vp->virtual_height / 2;
   150 	p.y -= vp->virtual_height / 2;
   168 	return p;
   151 	return p;
   169 }
   152 }
   170 
   153 
   171 void InitViewports()
       
   172 {
       
   173 	memset(_viewports, 0, sizeof(_viewports));
       
   174 	_active_viewports = 0;
       
   175 }
       
   176 
       
   177 void DeleteWindowViewport(Window *w)
   154 void DeleteWindowViewport(Window *w)
   178 {
   155 {
   179 	ClrBit(_active_viewports, w->viewport - _viewports);
       
   180 	w->viewport->width = 0;
   156 	w->viewport->width = 0;
   181 	w->viewport = NULL;
   157 	w->viewport = NULL;
   182 }
   158 }
   183 
   159 
   184 void AssignWindowViewport(Window *w, int x, int y,
   160 void AssignWindowViewport(Window *w, int x, int y,
   185 	int width, int height, uint32 follow_flags, ZoomLevel zoom)
   161 	int width, int height, uint32 follow_flags, ZoomLevel zoom)
   186 {
   162 {
   187 	ViewPort *vp;
   163 	assert(w->viewport == NULL);
   188 	Point pt;
   164 
   189 	uint32 bit;
   165 	ViewPort *vp = &(WP(w, vp_d).vp_data);
   190 
       
   191 	for (vp = _viewports, bit = 0; ; vp++, bit++) {
       
   192 		assert(vp != endof(_viewports));
       
   193 		if (vp->width == 0) break;
       
   194 	}
       
   195 	SetBit(_active_viewports, bit);
       
   196 
   166 
   197 	vp->left = x + w->left;
   167 	vp->left = x + w->left;
   198 	vp->top = y + w->top;
   168 	vp->top = y + w->top;
   199 	vp->width = width;
   169 	vp->width = width;
   200 	vp->height = height;
   170 	vp->height = height;
   201 
   171 
   202 	vp->zoom = zoom;
   172 	vp->zoom = zoom;
   203 
   173 
   204 	vp->virtual_width = ScaleByZoom(width, zoom);
   174 	vp->virtual_width = ScaleByZoom(width, zoom);
   205 	vp->virtual_height = ScaleByZoom(height, zoom);
   175 	vp->virtual_height = ScaleByZoom(height, zoom);
       
   176 
       
   177 	Point pt;
   206 
   178 
   207 	if (follow_flags & 0x80000000) {
   179 	if (follow_flags & 0x80000000) {
   208 		const Vehicle *veh;
   180 		const Vehicle *veh;
   209 
   181 
   210 		WP(w, vp_d).follow_vehicle = (VehicleID)(follow_flags & 0xFFFF);
   182 		WP(w, vp_d).follow_vehicle = (VehicleID)(follow_flags & 0xFFFF);
  1649 	);
  1621 	);
  1650 }
  1622 }
  1651 
  1623 
  1652 void MarkAllViewportsDirty(int left, int top, int right, int bottom)
  1624 void MarkAllViewportsDirty(int left, int top, int right, int bottom)
  1653 {
  1625 {
  1654 	const ViewPort *vp = _viewports;
  1626 	Window **wz;
  1655 	uint32 act = _active_viewports;
  1627 
  1656 	do {
  1628 	FOR_ALL_WINDOWS(wz) {
  1657 		if (act & 1) {
  1629 		ViewPort *vp = (*wz)->viewport;
       
  1630 		if (vp != NULL) {
  1658 			assert(vp->width != 0);
  1631 			assert(vp->width != 0);
  1659 			MarkViewportDirty(vp, left, top, right, bottom);
  1632 			MarkViewportDirty(vp, left, top, right, bottom);
  1660 		}
  1633 		}
  1661 	} while (vp++,act>>=1);
  1634 	}
  1662 }
  1635 }
  1663 
  1636 
  1664 void MarkTileDirtyByTile(TileIndex tile)
  1637 void MarkTileDirtyByTile(TileIndex tile)
  1665 {
  1638 {
  1666 	Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, GetTileZ(tile));
  1639 	Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, GetTileZ(tile));