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)); |