-
Notifications
You must be signed in to change notification settings - Fork 1
/
PixelToasterCommon.h
executable file
·264 lines (214 loc) · 5.3 KB
/
PixelToasterCommon.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
// Common code across all platforms
// Copyright © 2004-2007 Glenn Fiedler
// Part of the PixelToaster Framebuffer Library - http://www.pixeltoaster.com
#ifndef PIXELTOASTER_NO_CRT
#include <ctime>
#endif
namespace PixelToaster
{
// glenn's magical strcpy replacement with bram's template touch ...
template <int n> void magical_strcpy( char (&dest)[n], const char src[] )
{
unsigned int i = 0;
while ( i < n - 1 )
{
if ( src[i] == 0 )
break;
dest[i] = src[i];
i++;
}
dest[i] = 0;
}
// derive your platform's display implementation from this and it will handle all the mundane details for you
class DisplayAdapter : public DisplayInterface
{
public:
DisplayAdapter()
{
_listener = NULL;
_wrapper = NULL;
defaults();
}
~DisplayAdapter()
{
close();
_listener = NULL;
_wrapper = NULL;
}
bool open( const char title[], int width, int height, Output output, Mode mode )
{
close();
magical_strcpy(_title, title);
_width = width;
_height = height;
_output = output;
_mode = mode;
_open = true;
return true;
}
void close()
{
defaults();
}
bool open() const
{
return _open;
}
bool update( const TrueColorPixel pixels[], const Rectangle * dirtyBox )
{
if ( pixels )
return update( pixels, 0, dirtyBox );
else
return false;
}
bool update( const FloatingPointPixel pixels[], const Rectangle * dirtyBox )
{
if ( pixels )
return update( 0, pixels, dirtyBox );
else
return false;
}
const char * title() const
{
return _title;
}
void title( const char title[] )
{
magical_strcpy(_title, title);
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Mode mode() const
{
return _mode;
}
Output output() const
{
return _output;
}
void listener( Listener * listener )
{
_listener = listener;
}
Listener * listener() const
{
return _listener;
}
void wrapper( DisplayInterface * display )
{
_wrapper = display;
}
DisplayInterface * wrapper()
{
return _wrapper;
}
protected:
// note: override this "unified" update to implement your display update.
// only one of the pointers will be non-null, this allows you to avoid
// duplicating update code between truecolor and floating point update methods.
virtual bool update( const TrueColorPixel * trueColorPixels, const FloatingPointPixel * floatingPointPixels, const Rectangle * dirtyBox ) { return true; }
// this defaults is virtual, override it to add your own defaults
// but make sure you always call the superclass defaults in your overridden function!
// note: due to c++ constructor oddities, make sure you also call defaults in your own
// display ctor, otherwise it will only call this base version because the vtable is not
// setup yet. see the windows display for an example of this.
virtual void defaults()
{
_title[0] = 0;
_width = 0;
_height = 0;
_mode = Mode::FloatingPoint;
_output = Output::Default;
_open = false;
}
// switch to windowed output.
// override this to implement your own switch.
virtual bool windowed()
{
_output = Output::Windowed;
return true;
}
// switch to fullscreen output.
// override this to implement your own switch.
virtual bool fullscreen()
{
_output = Output::Fullscreen;
return true;
}
private:
char _title[256];
int _width;
int _height;
Mode _mode;
Output _output;
bool _open;
Listener * _listener;
DisplayInterface * _wrapper; // required for listener callbacks
};
#ifndef PIXELTOASTER_NO_CRT
// portable timer implementation for platforms without a specific high res timer
class PortableTimer : public PixelToaster::TimerInterface
{
public:
PortableTimer()
{
_resolution = 1.0 / CLOCKS_PER_SEC;
reset();
}
void reset()
{
_time = 0;
_timeCounter = clock();
_deltaCounter = _timeCounter;
}
double time()
{
clock_t counter = std::clock();
double delta = ( counter - _timeCounter ) * _resolution;
_timeCounter = counter;
_time += delta;
return _time;
}
double delta()
{
clock_t counter = std::clock();
double delta = ( counter - _deltaCounter ) * _resolution;
_deltaCounter = counter;
return delta;
}
double resolution()
{
return _resolution;
}
void wait(double seconds)
{
clock_t start = std::clock();
clock_t finish = start + clock_t( seconds / _resolution );
while ( std::clock() < finish );
}
private:
double _time; ///< current time in seconds
double _resolution; ///< timer resolution in seconds
clock_t _timeCounter; ///< time counter in clocks
clock_t _deltaCounter; ///< delta counter in clocks
};
#else
// dummy timer if we are not using CRT
class PortableTimer : public PixelToaster::TimerInterface
{
public:
PortableTimer() {}
void reset() {}
double time() { return 0.0f; }
double delta() { return 0.0f; }
double resolution() { return 0.0f; }
void wait( double seconds ) {}
};
#endif
}