comparison demos/qd.d @ 73:b706170e24a9 trunk

[svn r77] Fixed foreach on slice. Fixed some nested function problems when accessing outer function parameters. Major changes to handling of structs. Initial support for unions. Probably more...
author lindquist
date Wed, 31 Oct 2007 03:11:32 +0100
parents 835320b88ad6
children 2332006e1fa4
comparison
equal deleted inserted replaced
72:d7e764e62462 73:b706170e24a9
1 // modified version of scrapple.qd to work with llvmdc 1 module qd;
2 import std.stdio; 2
3 3 /*
4 //version(none) 4 import std.c.time: sleep;
5 void main() { 5 void main() {
6 screen(640, 480); 6 screen(640, 480);
7 pset(10, 10); 7 pset(10, 10);
8 line(0, 0, 100, 100, Box, Back(Red~Black)); 8 line(0, 0, 100, 100, Box, Back(Red~Black));
9 for (int i=0; i<=100; i+=10) { 9 for (int i=0; i<=100; i+=10) {
14 paint(200, 200, Red, Back=White); 14 paint(200, 200, Red, Back=White);
15 circle(100, 100, 50, 15, White); 15 circle(100, 100, 50, 15, White);
16 paint(200, 200, Black); 16 paint(200, 200, Black);
17 pset(10, 11); pset(10, 11, Black); 17 pset(10, 11); pset(10, 11, Black);
18 pset(10, 10); 18 pset(10, 10);
19 SDL_Delay(5000); 19 sleep(5);
20 } 20 }
21 */
21 22
22 extern(C) { 23 extern(C) {
23 struct SDL_Rect { 24 struct SDL_Rect {
24 short x, y; 25 short x, y;
25 ushort w, h; 26 ushort w, h;
48 uint SDL_MapRGBA(SDL_PixelFormat *format, ubyte r, ubyte g, ubyte b, ubyte a); 49 uint SDL_MapRGBA(SDL_PixelFormat *format, ubyte r, ubyte g, ubyte b, ubyte a);
49 void SDL_GetRGBA(uint pixel, SDL_PixelFormat *fmt, ubyte *r, ubyte *g, ubyte *b, ubyte *a); 50 void SDL_GetRGBA(uint pixel, SDL_PixelFormat *fmt, ubyte *r, ubyte *g, ubyte *b, ubyte *a);
50 int SDL_LockSurface(SDL_Surface *); 51 int SDL_LockSurface(SDL_Surface *);
51 void SDL_UnlockSurface(SDL_Surface *); 52 void SDL_UnlockSurface(SDL_Surface *);
52 SDL_Surface * SDL_SetVideoMode(int width, int height, int bpp, uint flags); 53 SDL_Surface * SDL_SetVideoMode(int width, int height, int bpp, uint flags);
54 SDL_Surface *SDL_CreateRGBSurface(uint flags, int width, int height, int depth, uint Rmask=0, uint Gmask=0, uint Bmask=0, uint Amask=0);
53 int SDL_Flip(SDL_Surface *); 55 int SDL_Flip(SDL_Surface *);
54 void SDL_Delay(uint); 56 void SDL_UpdateRect (SDL_Surface *screen, int x, int y, uint w, uint h);
57 int SDL_UpperBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);
58 alias SDL_UpperBlit SDL_BlitSurface;
59 int SDL_SetAlpha(SDL_Surface *surface, uint flags, ubyte alpha);
60 int SDL_SetColorKey(SDL_Surface *surface, uint flag, uint key);
61 int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, uint color);
55 const uint SDL_SWSURFACE=0; 62 const uint SDL_SWSURFACE=0;
56 const uint SDL_HWSURFACE=1; 63 const uint SDL_HWSURFACE=1;
57 const uint SDL_DOUBLEBUF=0x40000000; 64 const uint SDL_DOUBLEBUF=0x40000000;
58 const uint SDL_FULLSCREEN=0x80000000; 65 const uint SDL_FULLSCREEN=0x80000000;
66 const uint SDL_SRCALPHA=0x00010000;
67 const uint SDL_SRCCOLORKEY=0x00001000;
68 void SDL_Delay(uint ms);
69 uint SDL_GetTicks();
70
71 enum SDLKey {
72 Unknown = 0, First = 0,
73 Escape = 27,
74 LCtrl = 306,
75 }
76 enum SDLMod {
77 KMOD_NONE = 0x0000,
78 KMOD_LSHIFT= 0x0001, KMOD_RSHIFT= 0x0002,
79 KMOD_LCTRL = 0x0040, KMOD_RCTRL = 0x0080, KMOD_CTRL = 0x00C0,
80 KMOD_LALT = 0x0100, KMOD_RALT = 0x0200, KMOD_ALT = 0x0300,
81 KMOD_LMETA = 0x0400, KMOD_RMETA = 0x0800,
82 KMOD_NUM = 0x1000, KMOD_CAPS = 0x2000, KMOD_MODE = 0x4000,
83 KMOD_RESERVED = 0x8000
84 };
85
86 struct SDL_keysym { ubyte scancode; SDLKey sym; SDLMod mod; ushort unicode; }
87 enum SDL_EventType : ubyte {
88 NoEvent=0, Active, KeyDown, KeyUp,
89 MouseMotion, MouseButtonDown, MouseButtonUp,
90 JoyAxisMotion, JoyBallMotion, JoyHatMotion, JoyButtonDown, JoyButtonUp,
91 Quit, SysWMEvent
92 }
93 union SDL_Event {
94 SDL_EventType type;
95 struct Active { SDL_EventType type, gain, state; }; Active active;
96 struct Key { SDL_EventType type, which, state; SDL_keysym keysym; }; Key key;
97 struct Motion { SDL_EventType type, which, state; ushort x, y; short xrel, yrel; }; Motion motion;
98 struct Button { SDL_EventType type, which, button, state; ushort x, y; }; Button button;
99 struct Jaxis { SDL_EventType type, which, axis; short value; }; Jaxis jaxis;
100 struct Jball { SDL_EventType type, which, ball; short xrel, yrel; }; Jball jball;
101 struct Jhat { SDL_EventType type, which, hat, value; }; Jhat jhat;
102 struct Jbutton { SDL_EventType type, which, button, state; }; Jbutton jbutton;
103 struct Resize { SDL_EventType type; int w, h; }; Resize resize;
104 struct Expose { SDL_EventType type; }; Expose expose;
105 struct Quit { SDL_EventType type; }; Quit quit;
106 struct User { SDL_EventType type; int code; void *data1, data2; }; User user;
107 struct Syswm { SDL_EventType type; void *msg; }; Syswm syswm;
108 }
109
110 int SDL_PollEvent(SDL_Event *event);
59 } 111 }
60 112
61 SDL_Surface *display; 113 SDL_Surface *display;
62 114
63 void putpixel32(SDL_Surface *surf, int x, int y, ubyte[4] col) { 115 void putpixel32(int x, int y, ubyte[4] col) {
64 uint *bufp = cast(uint *)surf.pixels + y*surf.pitch/4 + x; 116 uint *bufp = cast(uint *)display.pixels + y*display.pitch/4 + x;
65 *bufp = SDL_MapRGBA(surf.format, col[0], col[1], col[2], col[3]); 117 *bufp = SDL_MapRGBA(display.format, col[0], col[1], col[2], col[3]);
66 } 118 }
67 119
68 void getpixel32(SDL_Surface *surf, int x, int y, ubyte[4] *col) { 120 void putpixel32(int x, int y, ubyte[3] col) {
69 uint *bufp = cast(uint *)surf.pixels + y*surf.pitch/4 + x; 121 uint *bufp = cast(uint *)display.pixels + y*display.pitch/4 + x;
70 SDL_GetRGBA(*bufp, surf.format, &(*col)[0], &(*col)[1], &(*col)[2], &(*col)[3]); 122 *bufp = SDL_MapRGBA(display.format, col[0], col[1], col[2], 0);
123 }
124
125 void getpixel32(int x, int y, ubyte[4] *col) {
126 uint *bufp = cast(uint *)display.pixels + y*display.pitch/4 + x;
127 SDL_GetRGBA(*bufp, display.format, &(*col)[0], &(*col)[1], &(*col)[2], &(*col)[3]);
71 } 128 }
72 129
73 struct rgb { 130 struct rgb {
74 ubyte[3] values; 131 ubyte[3] values;
132 ubyte r() { return values[0]; }
133 ubyte g() { return values[1]; }
134 ubyte b() { return values[2]; }
75 rgb opCat(rgb other) { 135 rgb opCat(rgb other) {
76 rgb res; 136 rgb res;
77 foreach (id, ref v; res.values) v=(values[id]+other.values[id])/2; 137 foreach (id, ref v; res.values) v=cast(ubyte)((values[id]+other.values[id])/2);
78 return res; 138 return res;
79 } 139 }
80 bool opEquals(rgb r) { 140 bool opEquals(rgb r) {
81 return values == r.values; 141 return values == r.values;
82 } 142 }
83 } 143 }
84 144
85 void putpixel(SDL_Surface *surf, int x, int y, rgb c) { 145 void putpixel(int x, int y, ubyte[4] col) {
86 if ( (x<0) || (y<0) || (x!<surf.w) || (y!<surf.h) ) return; 146 if ( (x<0) || (y<0) || (x!<display.w) || (y!<display.h) ) return;
87 putpixel32(surf, x, y, [c.values[0], c.values[1], c.values[2], 0]); 147 putpixel32(x, y, col);
148 }
149
150 void hline(int x, int y, int w, rgb r) {
151 hline(x, y, w, SDL_MapRGBA(display.format, r.values[0], r.values[1], r.values[2], 0));
152 }
153 void hline(int x, int y, int w, uint c) {
154 if ( (y<0) || (y!<display.h) ) return;
155 if (x<0) { w+=x; x=0; }
156 if (w<0) return;
157 if ( (x+w) !<display.w) w=display.w-x-1;
158 auto cur = cast(uint *)display.pixels + y*display.pitch/4 + x;
159 foreach (ref value; cur[0..w+1]) value=c;
88 } 160 }
89 161
90 const rgb White={[255, 255, 255]}; 162 const rgb White={[255, 255, 255]};
91 const rgb Black={[0, 0, 0]}; 163 const rgb Black={[0, 0, 0]};
92 const rgb Red={[255, 0, 0]}; 164 const rgb Red={[255, 0, 0]};
93 const rgb Green={[0, 255, 0]}; 165 const rgb Green={[0, 255, 0]};
94 const rgb Blue={[0, 0, 255]}; 166 const rgb Blue={[0, 0, 255]};
167 const rgb Yellow={[255, 255, 0]};
168 const rgb Cyan={[0, 255, 255]};
169 const rgb Purple={[255, 0, 255]};
95 rgb color=White; 170 rgb color=White;
96 rgb back=Black; 171 rgb back=Black;
97 172
98 template failfind(U, T...) { 173 template failfind(U, T...) {
99 static if (T.length) 174 static if (T.length)
121 typedef rgb box_rgb; 196 typedef rgb box_rgb;
122 box_rgb Box(rgb r) { return cast(box_rgb) r; } 197 box_rgb Box(rgb r) { return cast(box_rgb) r; }
123 box_rgb Box() { return cast(box_rgb) color; } 198 box_rgb Box() { return cast(box_rgb) color; }
124 alias Back Fill; 199 alias Back Fill;
125 200
201 bool doFlip=true;
202 void flip() { SDL_Flip(display); }
203 void flip(bool target) { doFlip=target; }
204 scope class groupDraws {
205 bool wasOn;
206 this() { wasOn=doFlip; flip=false; }
207 ~this() { if (wasOn) { flip=true; flip; } }
208 }
209
126 void execParams(T...)(T params) { 210 void execParams(T...)(T params) {
211 const int bcol=select!(back_rgb, T);
212 static if (bcol != -1) back=cast(rgb) params[bcol];
127 const int col=select!(rgb, T); 213 const int col=select!(rgb, T);
128 static if (col != -1) color=params[col]; 214 static if (col != -1) color=params[col];
129 const int bcol=select!(back_rgb, T); 215 else static if (bcol != -1) color=back;
130 static if (bcol != -1) back=cast(rgb) params[bcol];
131 const int boxcol=select!(box_rgb, T); 216 const int boxcol=select!(box_rgb, T);
132 static if (boxcol != -1) color=cast(rgb) params[boxcol]; 217 static if (boxcol != -1) color=cast(rgb) params[boxcol];
133 } 218 }
134 219
220 void tintfill(int x1, int y1, int x2, int y2, rgb color) {
221 SDL_LockSurface(display);
222 scope(exit) { SDL_UnlockSurface(display); if (doFlip) flip; }
223 ubyte[4] c;
224 for (int x=x1; x<x2; ++x) {
225 for (int y=y1; y<y2; ++y) {
226 getpixel32(x, y, &c);
227 c[0]=cast(ubyte)(c[0]*178+color.r*77)>>8;
228 c[1]=cast(ubyte)(c[1]*178+color.g*77)>>8;
229 c[2]=cast(ubyte)(c[2]*178+color.b*77)>>8;
230 putpixel32(x, y, c);
231 }
232 }
233 }
234
135 void pset(T...)(int x, int y, T params) { 235 void pset(T...)(int x, int y, T params) {
136 SDL_LockSurface(display); 236 SDL_LockSurface(display);
137 scope(exit) { SDL_UnlockSurface(display); SDL_Flip(display); } 237 scope(exit) { SDL_UnlockSurface(display); if (doFlip) flip; }
138 execParams(params); 238 execParams(params);
139 putpixel(display, x, y, color); 239 putpixel32(x, y, color.values);
140 } 240 }
141 241
142 rgb pget(int x, int y) { 242 rgb pget(int x, int y) {
143 SDL_LockSurface(display); 243 SDL_LockSurface(display);
144 scope(exit) SDL_UnlockSurface(display); 244 scope(exit) SDL_UnlockSurface(display);
145 ubyte[4] c; 245 ubyte[4] c;
146 getpixel32(display, x, y, &c); 246 getpixel32(x, y, &c);
147 rgb res; res.values[]=c[0..3]; return res; 247 rgb res; res.values[]=c[0..3]; return res;
148 } 248 }
149 249
150 void swap(T)(ref T a, ref T b) { T c=a; a=b; b=c; } 250 void swap(T)(ref T a, ref T b) { T c=a; a=b; b=c; }
151 251 T abs(T)(T a) { return (a<0) ? -a : a; }
152 T abs(T)(T f) { return f < 0 ? -f : f; }
153 252
154 void bresenham(bool countUp=true, bool steep=false)(int x0, int y0, int x1, int y1) { 253 void bresenham(bool countUp=true, bool steep=false)(int x0, int y0, int x1, int y1) {
155 auto deltax = x1 - x0, deltay = y1 - y0; 254 auto deltax = x1 - x0, deltay = y1 - y0;
156 static if (steep) { 255 static if (steep) {
157 auto Δerror = cast(float)deltax / cast(float)deltay; 256 auto Δerror = cast(float)deltax / cast(float)deltay;
161 auto Δerror = cast(float)deltay / cast(float)deltax; 260 auto Δerror = cast(float)deltay / cast(float)deltax;
162 auto var2 = y0; 261 auto var2 = y0;
163 const string name="x"; 262 const string name="x";
164 } 263 }
165 auto error = 0f; 264 auto error = 0f;
265 ubyte[4] col; col[0..3]=color.values;
166 for (auto var1 = mixin(name~'0'); var1 <= mixin(name~'1'); ++var1) { 266 for (auto var1 = mixin(name~'0'); var1 <= mixin(name~'1'); ++var1) {
167 static if (steep) putpixel(display, var2, var1, color); 267 static if (steep) putpixel(var2, var1, col);
168 else putpixel(display, var1, var2, color); 268 else putpixel(var1, var2, col);
169 error += Δerror; 269 error += Δerror;
170 if (abs(error) >= 1f) { static if (countUp) { var2++; error -= 1f; } else { var2--; error += 1f; }} 270 if (abs(error) >= 1f) { static if (countUp) { var2++; error -= 1f; } else { var2--; error += 1f; }}
171 } 271 }
172 } 272 }
173 273
176 276
177 void line(T...)(int x0, int y0, int x1, int y1, T p) { 277 void line(T...)(int x0, int y0, int x1, int y1, T p) {
178 execParams(p); 278 execParams(p);
179 static if (select!(back_rgb, T)!=-1) { 279 static if (select!(back_rgb, T)!=-1) {
180 SDL_LockSurface(display); 280 SDL_LockSurface(display);
181 scope(exit) { SDL_UnlockSurface(display); SDL_Flip(display); } 281 scope(exit) { SDL_UnlockSurface(display); if (doFlip) flip; }
182 auto xend=max(x0, x1); 282 auto yend=max(y0, y1);
183 for (int x=min(x0, x1); x<=xend; ++x) { 283 for (int y=min(y0, y1); y<=yend; ++y) {
184 auto yend=max(y0, y1); 284 hline(min(x0, x1), y, max(x0, x1)-min(x0, x1), back);
185 for (int y=min(y0, y1); y<=yend; ++y) {
186 putpixel(display, x, y, back);
187 }
188 } 285 }
189 } 286 }
190 static if (select!(box_rgb, T)!=-1) { 287 static if (select!(box_rgb, T)!=-1) {
191 line(x0, y0, x1, y0); 288 line(x0, y0, x1, y0);
192 line(x1, y0, x1, y1); 289 line(x1, y0, x1, y1);
193 line(x1, y1, x0, y1); 290 line(x1, y1, x0, y1);
194 line(x0, y1, x0, y0); 291 line(x0, y1, x0, y0);
195 } 292 }
196 static if (select!(box_rgb, T)+select!(back_rgb, T)==-2) { 293 static if (select!(box_rgb, T)+select!(back_rgb, T)==-2) {
197 SDL_LockSurface(display); 294 SDL_LockSurface(display);
198 scope(exit) { SDL_UnlockSurface(display); SDL_Flip(display); } 295 scope(exit) { SDL_UnlockSurface(display); if (doFlip) flip; }
199 bool steep = abs(y1 - y0) > abs(x1 - x0); 296 bool steep = abs(y1 - y0) > abs(x1 - x0);
200 void turn() { swap(x0, x1); swap(y0, y1); } 297 void turn() { swap(x0, x1); swap(y0, y1); }
201 if (steep) { if (y1 < y0) turn; } 298 if (steep) { if (y1 < y0) turn; }
202 else { if (x1 < x0) turn; } 299 else { if (x1 < x0) turn; }
203 bool stepUp=steep ? (x0 < x1) : (y0 < y1); 300 bool stepUp=steep ? (x0 < x1) : (y0 < y1);
224 auto ychange=xradius*xradius*"~(first?"1":"(1-2*yradius)")~"; 321 auto ychange=xradius*xradius*"~(first?"1":"(1-2*yradius)")~";
225 auto error=0; 322 auto error=0;
226 auto stopx="~(first?"y2square*xradius":"0")~"; 323 auto stopx="~(first?"y2square*xradius":"0")~";
227 auto stopy="~(first?"0":"x2square*yradius")~"; 324 auto stopy="~(first?"0":"x2square*yradius")~";
228 while (stopx"~(first?">=":"<=")~"stopy) { 325 while (stopx"~(first?">=":"<=")~"stopy) {
229 putpixel(display, cx+x, cy+y, color); 326 putpixel(cx+x, cy+y, col);
230 putpixel(display, cx+x, cy-y, color); 327 putpixel(cx+x, cy-y, col);
231 putpixel(display, cx-x, cy+y, color); 328 putpixel(cx-x, cy+y, col);
232 putpixel(display, cx-x, cy-y, color); 329 putpixel(cx-x, cy-y, col);
233 "~yx~"++; 330 "~yx~"++;
234 stop"~yx~"+="~xy~"2square; 331 stop"~yx~"+="~xy~"2square;
235 error+="~yx~"change; 332 error+="~yx~"change;
236 "~yx~"change+="~xy~"2square; 333 "~yx~"change+="~xy~"2square;
237 if ((2*error+"~xy~"change)>0) { 334 if ((2*error+"~xy~"change)>0) {
242 } 339 }
243 } 340 }
244 "; 341 ";
245 } 342 }
246 343
247 void circle(T...)(int cx, int cy, int xradius, T t) { 344 import std.stdio;
345 void circle(T...)(T t) {
346 static assert(T.length!<3, "Circle: Needs x, y and radius");
347 int cx=t[0], cy=t[1], xradius=t[2];
248 SDL_LockSurface(display); 348 SDL_LockSurface(display);
249 scope(exit) { SDL_UnlockSurface(display); SDL_Flip(display); } 349 scope(exit) { SDL_UnlockSurface(display); if (doFlip) flip; }
250 execParams(t); 350 execParams(t[3..$]);
251 auto yradius=xradius; 351 auto yradius=xradius;
252 static if (T.length && is(T[0]: int)) yradius=t[0]; 352 if (xradius!>0) return;
353 static if (T.length>3 && is(T[3]: int)) yradius=t[3];
253 static if (select!(back_rgb, T) != -1) { 354 static if (select!(back_rgb, T) != -1) {
254 auto ratio=xradius*1f/yradius; 355 auto ratio=xradius*1f/yradius;
356 auto back_sdl=SDL_MapRGBA(display.format, back.values[0], back.values[1], back.values[2], 0);
255 for (int i=0; i<=yradius; ++i) { 357 for (int i=0; i<=yradius; ++i) {
256 ushort j=cast(ushort)(sqrt(cast(real)(yradius*yradius-i*i))*ratio); 358 ushort j=cast(ushort)(sqrt(cast(real)(yradius*yradius-i*i))*ratio);
257 for (int lx=cx-j; lx<=cx+j; ++lx) putpixel(display, lx, cy+i, back); 359 hline(cx-j, cy+i, 2*j, back_sdl);
258 for (int lx=cx-j; lx<=cx+j; ++lx) putpixel(display, lx, cy-i, back); 360 hline(cx-j, cy-i, 2*j, back_sdl);
259 } 361 }
260 } 362 }
261 auto x2square=2*xradius*xradius; 363 auto x2square=2*xradius*xradius;
262 auto y2square=2*yradius*yradius; 364 auto y2square=2*yradius*yradius;
365 ubyte[4] col; col[0..3]=color.values;
263 { mixin(circle_bresenham_pass!(true).str); } 366 { mixin(circle_bresenham_pass!(true).str); }
264 { mixin(circle_bresenham_pass!(false).str); } 367 { mixin(circle_bresenham_pass!(false).str); }
368 }
369
370 float distance(float x1, float y1, float x2, float y2) {
371 auto x=x1-x2, y=y1-y2;
372 return sqrt(x*x+y*y);
265 } 373 }
266 374
267 struct floodfill_node { 375 struct floodfill_node {
268 int x, y; 376 int x, y;
269 static floodfill_node opCall(int x, int y) { 377 static floodfill_node opCall(int x, int y) {
273 } 381 }
274 } 382 }
275 383
276 void paint(T...)(int x, int y, T t) { 384 void paint(T...)(int x, int y, T t) {
277 SDL_LockSurface(display); 385 SDL_LockSurface(display);
278 scope(exit) { SDL_UnlockSurface(display); SDL_Flip(display); } 386 scope(exit) { SDL_UnlockSurface(display); if (doFlip) flip; }
279 execParams(t); 387 execParams(t);
280 bool border=true; 388 bool border=true;
281 if (select!(back_rgb, T) == -1) { 389 if (select!(back_rgb, T) == -1) {
282 back=pget(x, y); 390 back=pget(x, y);
283 border=false; 391 border=false;
298 int w=x, e=x; 406 int w=x, e=x;
299 if (w<display.w) do w++; while ((w<display.w) && check(pget(w, y))); 407 if (w<display.w) do w++; while ((w<display.w) && check(pget(w, y)));
300 if (e>=0) do e--; while (e>=0 && check(pget(e, y))); 408 if (e>=0) do e--; while (e>=0 && check(pget(e, y)));
301 //SDL_Flip(display); 409 //SDL_Flip(display);
302 for (int i=e+1; i<w; ++i) { 410 for (int i=e+1; i<w; ++i) {
303 putpixel(display, i, y, color); 411 putpixel32(i, y, color.values);
304 if (y && check(pget(i, y-1)) && ((i==w-1)||!check(pget(i+1, y-1)))) queue ~= node(i, y-1); 412 if (y && check(pget(i, y-1)) && ((i==w-1)||!check(pget(i+1, y-1)))) queue ~= node(i, y-1);
305 if ((y < display.h-1) && check(pget(i, y+1)) && ((i==w-1)||!check(pget(i+1, y+1)))) queue ~= node(i, y+1); 413 if ((y < display.h-1) && check(pget(i, y+1)) && ((i==w-1)||!check(pget(i+1, y+1)))) queue ~= node(i, y+1);
306 } 414 }
307 } 415 }
308 } 416 }
309 } 417 }
310 } 418 }
311 419
312 void screen(size_t w, size_t h) { 420 struct screen {
313 display = SDL_SetVideoMode(w, h, 32, SDL_SWSURFACE); 421 static {
314 } 422 void opCall(size_t w, size_t h) {
315 423 display = SDL_SetVideoMode(w, h, 32, SDL_SWSURFACE | SDL_DOUBLEBUF);
316 void cls() { line(0, 0, display.w-1, display.h-1, Fill=Black); } 424 }
425 int width() { return display.w; }
426 int height() { return display.h; }
427 }
428 }
429
430
431 void cls(rgb fill=Black) { line(0, 0, display.w-1, display.h-1, Fill=fill); }
432
433 void events(void delegate(int, bool) key=null, void delegate(int, int, ubyte, bool) mouse=null) {
434 SDL_Event evt;
435 while (SDL_PollEvent(&evt)) {
436 switch (evt.type) {
437 case SDL_EventType.MouseMotion:
438 with (evt.motion) if (mouse) mouse(x, y, 0, false);
439 break;
440 case SDL_EventType.MouseButtonDown:
441 with (evt.button) if (mouse) mouse(x, y, button, true);
442 break;
443 case SDL_EventType.MouseButtonUp:
444 with (evt.button) if (mouse) mouse(x, y, button, false);
445 break;
446 case SDL_EventType.KeyDown:
447 if (key) key(evt.key.keysym.sym, true);
448 case SDL_EventType.KeyUp:
449 if (key) key(evt.key.keysym.sym, false);
450 break;
451 case SDL_EventType.Quit:
452 throw new Error("Quit");
453 break;
454 default: break;
455 }
456 }
457 }
458
459 void events(void delegate(int) key, void delegate(int, int, ubyte, bool) mouse=null) {
460 events((int a, bool b) {
461 if (b) key(a);
462 }, mouse);
463 }
464
465 void events(void delegate(int) key, void delegate(int, int) mouse) {
466 events(key, (int x, int y, ubyte b, bool p) { mouse(x, y); });
467 }
468
469 void events(void delegate(int, bool) key, void delegate(int, int) mouse) {
470 events(key, (int x, int y, ubyte b, bool p) { mouse(x, y); });
471 }