-Started to move stuff from library back to main game
[supertux.git] / src / collision_grid_iterator.h
1 //  $Id$
2 // 
3 //  SuperTux
4 //  Copyright (C) 2005 Matthias Braun <matze@braunis.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 // 
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 //  02111-1307, USA.
20
21 #ifndef __COLLISION_GRID_ITERATOR_H__
22 #define __COLLISION_GRID_ITERATOR_H__
23
24 #include "math/rectangle.h"
25
26 using namespace SuperTux;
27
28 class CollisionGrid;
29
30 class CollisionGridIterator
31 {
32 public:
33   CollisionGridIterator(CollisionGrid& newgrid, const Rectangle& bbox)
34     : grid(newgrid)
35   {
36     start_x = int(bbox.p1.x / grid.cell_width) - 2;
37     if(start_x < 0)
38       start_x = 0;
39     x = start_x;
40         
41     y = int(bbox.p1.y / grid.cell_height) - 2;
42     if(y < 0)
43       y = 0;
44     
45     end_x = int(bbox.p2.x / grid.cell_width) + 2;
46     if(end_x > (int) grid.cells_x)
47       end_x = grid.cells_x;
48     
49     end_y = int(bbox.p2.y / grid.cell_height) + 2;
50     if(end_y > (int) grid.cells_y)
51       end_y = grid.cells_y;
52
53     if(start_x >= end_x) {
54       printf("bad region.\n");
55       y = 0;
56       end_y = 0;
57       return;
58     }
59
60     timestamp = grid.iterator_timestamp++;
61     entry = 0;
62   }
63
64   MovingObject* next()
65   {
66     CollisionGrid::ObjectWrapper* wrapper = next_wrapper();
67     if(wrapper == 0)
68       return 0;
69         
70     return wrapper->object;
71   }
72
73 private:
74   friend class CollisionGrid;
75
76   CollisionGrid::ObjectWrapper* next_wrapper() 
77   {
78     CollisionGrid::ObjectWrapper* wrapper;
79     
80     do {
81       while(entry == 0) {
82         if(y >= end_y)
83           return 0;
84         
85         entry = grid.grid[y*grid.cells_x + x];
86         x++;
87         if(x >= end_x) {
88           x = start_x;
89           y++;
90         }
91       }
92       
93       wrapper = entry->object_wrapper;
94       entry = entry->next;
95     } while(wrapper->timestamp == timestamp);
96     
97     wrapper->timestamp = timestamp;
98     
99     return wrapper;
100   }
101     
102   CollisionGrid& grid;
103   CollisionGrid::GridEntry* entry;
104   int x, y;
105   int start_x, end_x, end_y;
106   int timestamp;
107 };
108
109 #endif
110