Changeset 343
- Timestamp:
- 05/28/08 13:29:08 (6 months ago)
- Files:
-
- trunk/qd/SDL_ttf.d (modified) (4 diffs)
- trunk/qd/dsss.conf (modified) (2 diffs)
- trunk/qd/dt.d (modified) (14 diffs)
- trunk/qd/qd.d (modified) (4 diffs)
- trunk/qd/test11.d (modified) (1 diff)
- trunk/qd/test13.d (modified) (6 diffs)
- trunk/qd/test2.d (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/qd/SDL_ttf.d
r340 r343 5 5 6 6 struct fontsettings { 7 bool bold=false; 8 bool italic=false; 9 bool underline=false; 7 bool bold, italic, underline; 8 rgb color=Black; int size=14; 10 9 } 11 10 12 11 import std.string: toStringz, toString; 13 12 import std.file: read; 13 import tools.base; 14 14 15 15 const SDL_Color SDL_White={255, 255, 255, 0}; 16 16 17 TTF_FontClass standard;17 TTF_FontClass[int] standard; 18 18 void initFont(int size = 14, string name="Vera.ttf") { 19 standard=new TTF_FontClass(read(name), size); 20 } 21 22 void print(int x, int y, Align how, string what) { 23 if (!standard) initFont(); 24 auto surf=standard.render(what); 19 standard[size] = new TTF_FontClass(read(name), size); 20 } 21 22 int htoi(string s) { 23 int res; 24 foreach (ch; s) { 25 if (ch >= '0' && ch <= '9') { res = res * 16 + (ch - '0'); continue; } 26 if (ch >= 'a' && ch <= 'f') ch -= ('a' - 'A'); 27 if (ch >= 'A' && ch <= 'F') { res = res * 16 + (ch - 'A') + 10; continue; } 28 throw new Exception("Not a hexadecimal string: "~s); 29 } 30 return res; 31 } 32 33 void prettyprint(int x, int y, Align how, string text, fontsettings deflt = Init!(fontsettings)) { 34 string[] chunks; 35 fontsettings[] sets; 36 Stuple!(string, fontsettings)[] stack; 37 fontsettings fs_top() { 38 if (stack.length) { 39 return stack[$-1]._1; 40 } else return deflt; 41 } 42 fontsettings fs_pop(string compare) { 43 if (stack[$-1]._0 != compare) 44 throw new Exception("Mismatched closing tag: expected "~stack[$-1]._0~", got "~compare); 45 return .pop(stack)._1; 46 } 47 void push(string text, string tag, void delegate(ref fontsettings fs) dg) { 48 chunks ~= text; 49 sets ~= fs_top(); 50 stack ~= stuple(tag, fs_top()); dg(stack[$-1]._1); 51 } 52 void pop(string text, string tag) { 53 chunks ~= text; 54 sets ~= fs_pop(tag); 55 } 56 void delegate(string, ref string) close_tag(string _tag) { 57 return _tag /apply/ (string tag, string pre, ref string post) { pop(pre, tag); }; 58 } 59 void delegate(string, ref string) [string] tags = [ 60 "[b]"[]: (string pre, ref string post) { 61 push(pre, "b", (ref fontsettings fs) { fs.bold = true; }); 62 }, "[/b]": close_tag("b"), 63 "[i]": (string pre, ref string post) { 64 push(pre, "i", (ref fontsettings fs) { fs.italic = true; }); 65 }, "[/i]": close_tag("i"), 66 "[u]": (string pre, ref string post) { 67 push(pre, "u", (ref fontsettings fs) { fs.underline = true; }); 68 }, "[/u]": close_tag("u"), 69 "[color ": (string pre, ref string post) { 70 string color; ptuple(color, post) = post.splitAt("]"); 71 // color.length != 3 || color.length != 6 -- see, it's shorter :) 72 if (!color.startsWith("#") || color.length != 3 /or/ 6) 73 throw new Exception("Colors except #xxx and #xxxxxx not supported."); 74 color = color [1 .. $]; 75 if (color.length == 3) color = color[0]~"0"~color[1]~"0"~color[2]~"0"; 76 auto res = rgb(color[0 .. 2].htoi(), color[2 .. 4].htoi(), color[4 .. 6].htoi()); 77 push(pre, "color", (ref fontsettings fs) { fs.color = res; logln("fs.color: ", fs.color); }); 78 }, "[/color]": close_tag("color") 79 ]; 80 text.glomp_parse(tags, (string s) { 81 if (stack.length) throw new Exception("Unclosed tag: "~stack[$-1]._0); 82 if (s.length) { chunks ~= s; sets ~= deflt; } 83 }); 84 print(x, y, how, sets, chunks); 85 } 86 87 void print(int x, int y, Align how, fontsettings[] settings, string[] strings) in { 88 assert(settings.length == strings.length); 89 } body { 90 auto surfs = new Area[strings.length]; 91 int width, height; 92 foreach (i, str; strings) { 93 auto s = settings[i]; 94 if (!(s.size in standard)) initFont(s.size); 95 surfs[i] = standard[s.size].render(str, s); 96 width += surfs[i].width; 97 if (surfs[i].height > height) height = surfs[i].height; 98 } 99 auto target = display.select(pt(x, y), pt(width, height), how); 100 foreach (surf; surfs) { 101 target.blit(surf, Top|Left); 102 target.width = surf.width - width; // yes this is correct. 103 width -= surf.width; 104 } 105 } 106 107 void print(int x, int y, Align how, rgb col, string what) { 108 if (!(14 in standard)) initFont(); 109 fontsettings foo; foo.color = col; 110 auto surf=standard[14].render(what, foo); 25 111 display.select(surf.size, pt(x, y), how).blit(surf); 26 112 SDL_FreeSurface(surf.surface); 27 113 } 28 114 29 void print(pt p, Align how, string what) { print(p.x, p.y, how, what); } 30 void print(Area where, Align how, string what) { 31 if (!standard) initFont(); 32 auto surf = standard.render(what); 33 where.blit(surf, how); 34 SDL_FreeSurface(surf.surface); 35 } 115 void print(pt p, Align how, rgb col, string what) { print(p.x, p.y, how, col, what); } 36 116 37 117 import std.stdio; … … 50 130 } 51 131 int curStyle; 52 private SDL_Surface *_render(char[] text, SDL_Color fg,fontsettings s=Default, int rendermode=2, SDL_Color *bg=null) {132 private SDL_Surface *_render(char[] text, fontsettings s=Default, int rendermode=2, SDL_Color *bg=null) { 53 133 //logln("Rendering ", text); 54 134 /// Make sure no two routines change font settings at the same time … … 61 141 switch(rendermode) { 62 142 case 0: // Solid 63 return TTF_RenderUTF8_Solid(font, toStringz(text), fg);143 return TTF_RenderUTF8_Solid(font, toStringz(text), s.color.toSDL()); 64 144 case 1: // Shaded 65 145 if (!bg) throw new Exception("Shaded selected but no background color given"); 66 return TTF_RenderUTF8_Shaded(font, toStringz(text), fg, *bg);146 return TTF_RenderUTF8_Shaded(font, toStringz(text), s.color.toSDL(), *bg); 67 147 case 2: // Blended 68 return TTF_RenderUTF8_Blended(font, toStringz(text), fg);148 return TTF_RenderUTF8_Blended(font, toStringz(text), s.color.toSDL()); 69 149 default: throw new Exception("Invalid case"); 70 150 } … … 72 152 assert(false); 73 153 } 74 Area render(string text, SDL_Color fg=SDL_White, fontsettings s=Default) { 75 auto res=_render(text, fg, s); 154 Area render(string text, fontsettings s=Default) { 155 if (!text.length) return Area(SDL_CreateRGBSurface(0, 0, 0, 32)); 156 auto res=_render(text, s); 76 157 if (!res) throw new Exception("Couldn't render "~'"'~text~'"'~": "~.toString(SDL_GetError)); 77 158 return Area(pt(0, 0), pt(res.w, res.h), res); trunk/qd/dsss.conf
r342 r343 3 3 type=sourcelibrary 4 4 [dt.d] 5 buildflags=-L-lSDL - g -profile5 buildflags=-L-lSDL -L-lSDL_ttf -g -O 6 6 # [test.d] 7 7 # buildflags=-L-lSDL 8 8 [test2.d] 9 buildflags=-L-lSDL -L-lSDL_ttf -g -O -release -inline9 buildflags=-L-lSDL -L-lSDL_ttf -g 10 10 [cellular.d] 11 11 buildflags=-L-lSDL -g -J. -O -release -inline -q,-march=nocona … … 25 25 [test11.d] 26 26 buildflags=-L-lSDL -L-lSDL_ttf -g 27 [test12.d]28 buildflags=-L-lSDL -L-lSDL_ttf -g27 # [test12.d] 28 # buildflags=-L-lSDL -L-lSDL_ttf -g 29 29 [ff.d] 30 30 buildflags=-L-lSDL -L-lSDL_ttf -O 31 [test13.d]32 buildflags=-L-lSDL-O -release -inline31 # [test13.d] 32 # buildflags=-L-lSDL -L-lSDL_ttf -O -release -inline trunk/qd/dt.d
r339 r343 6 6 import std.stdio, std.c.time: time; 7 7 import std.math, std.random, std.perf; 8 import qd ;8 import qd, dglut.vector; 9 9 10 10 float randf() { return (cast(float)rand())/(cast(float)(typeof(rand()).max)); } … … 19 19 20 20 class WorldThing : Thing { 21 int x, y, radius; 22 mixin This!("x, y, radius"); 21 vec2f pos; 22 int radius; 23 mixin This!("pos, radius"); 23 24 bool collide(WorldThing other) { return distance(other)<radius+other.radius; } 24 float distance(WorldThing other) { 25 static int sqr(int e) { return e*e; } 26 return sqrt(cast(float)(sqr(x-other.x)+sqr(y-other.y))); 27 } 25 float distance(WorldThing other) { return (other.pos - pos).length(); } 28 26 } 29 27 30 28 class LivingThing : WorldThing { 31 29 private { 32 float life;30 int life; 33 31 void delegate(LivingThing) onDeath; 34 32 } 35 void damage(float howmuch) { life-=howmuch; if (life!>0) onDeath(this); } 36 mixin This!("onDeath, super(x, y, radius), life=10"); 33 void damage(int howmuch) { life-=howmuch; if (life!>0) onDeath(this); } 34 void die() { damage(life); onDeath(this); } 35 mixin This!("onDeath, super(pos, radius), life=10"); 37 36 } 38 37 39 38 interface MovingThing { 40 void getMotionVector(ref float dx, ref float dy); 41 } 42 39 vec2f getMotionVector(); 40 } 41 42 import dglut.vector; 43 43 class Path { 44 struct Point { 45 float x, y; 46 static Point opCall(float x, float y) { Point res; res.x=x; res.y=y; return res; } 47 } 48 Point[] points; 44 vec2f[] points; 49 45 bool loop; 50 this(bool loop, Point[] points...) { this.loop=loop; this.points=points; }46 this(bool loop, vec2f[] points...) { this.loop=loop; this.points=points.dup; } 51 47 class Train { 52 48 private { 53 49 size_t cur; 54 50 float speed; 55 Pointpos;51 vec2f pos; 56 52 void delegate() done; 57 53 } 58 float dx, dy;54 vec2f delta; 59 55 mixin This!("pos, speed, done, cur=0"); 60 56 void update() { … … 63 59 // find the next point that's more than 1 unit away from me 64 60 do { 65 d x=points[cur].x-pos.x; dy=points[cur].y-pos.y;66 len =sqrt(dx*dx+dy*dy);61 delta = points[cur] - pos; 62 len = delta.length(); 67 63 } while (len!>1 && (++cur)<points.length); 68 64 if (cur==points.length) { … … 70 66 return; 71 67 } 72 d x/=len/speed; dy/=len/speed;73 pos .x+=dx; pos.y+=dy;68 delta /= len/speed; 69 pos += delta; 74 70 } 75 71 } … … 113 109 //void draw() { circle(x, y, radius, Black, Fill=Blue~White~White); } 114 110 void draw() { 115 bufferedCircle(x, y, radius, Black, Fill=Blue~White~White); 116 if (life<maxlife) circle(x, y, cast(int)(radius*0.8*(1f-life/maxlife)), Fill=Background); 117 } 118 void getMotionVector(ref float dx, ref float dy) { dx=train.dx; dy=train.dy; } 111 bufferedCircle(pos.to!(int).tuple, radius, Black, Fill=Blue~White~White); 112 if (life<maxlife) circle(pos.to!(int).tuple, cast(int)(radius*0.8*(1f-life * 1f / maxlife)), Background~Red, Fill=Background~Red); 113 .print(pos.to!(int).tuple, Center, Black, Format(life)); 114 } 115 override vec2f getMotionVector() { return train.delta; } 119 116 void damage(typeof(life) d) { 120 117 super.damage(d); 121 if (life!>0) addEffect!(RingEffect)(Blue~White~White, x, y, 10, 15);118 if (life!>0) addEffect!(RingEffect)(Blue~White~White, pos, 10, 15); 122 119 } 123 120 void update() { 124 121 train.update; 125 x=cast(int)train.pos.x; 126 y=cast(int)train.pos.y; 122 pos = train.pos; 127 123 } 128 124 float speed; 129 void die() { onDeath(this); life=0; }130 125 void delegate() win; 131 126 private { 132 float maxlife;127 int maxlife; 133 128 Path path; 134 129 Path.Train train; 135 130 void initTrain() { 136 train=path.new Train( Path.Point(x, y), speed, win);131 train=path.new Train(pos, speed, win); 137 132 } 138 133 long id; 139 134 } 140 mixin This!("path, speed, win, id, super(onDeath, x, y, radius=20, life=20), #maxlife=life; #initTrain; "); 141 } 142 143 float distance(float x, float y, float x2, float y2) { 144 return sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2)); 145 } 146 147 void normalize(ref float x, ref float y, float div) { 148 auto len=x*x+y*y; 149 if (len==0) return; 150 len=sqrt(len); 151 x/=len/div; y/=len/div; 135 mixin This!("path, speed, win, id, super(onDeath, pos, radius=20, life=20), #maxlife=life; #initTrain; "); 152 136 } 153 137 154 138 class Rocket : LivingThing { 155 139 TargetGroup targets; 156 float fx, fy; 157 float dx=0f, dy=0f; 140 vec2f delta; 158 141 struct Settings { 159 float speed, damage, aim, momentum; 160 int lifetime; 161 bool linger; 162 bool punchthrough; 142 float speed, aim, momentum; 143 int damage, lifetime; 144 bool linger, punchthrough, retarget; 163 145 } 164 146 Settings settings; 165 mixin This!("settings, targets, super(onDeath, x, y, radius=3, life=10)166 #fx=cast(float)x; #fy=cast(float)y; #life=settings.damage; ");147 mixin This!("settings, targets, super(onDeath, pos, radius=3, life=10) 148 #life=settings.damage; #delta=vec2f(0); "); 167 149 LivingThing enemy; 168 150 void draw() { 169 151 //line(x, y, enemy.x, enemy.y, White); 170 bufferedCircle( x, y, radius, Fill=Black);152 bufferedCircle(pos.to!(int).tuple, radius, Fill=Black); 171 153 } 172 154 void damage(typeof(life) d) { 173 155 super.damage(d); 174 if (life!>0) addEffect!(RingEffect)(Red, x, y, 3, 3);156 if (life!>0) addEffect!(RingEffect)(Red, pos, 3, 3); 175 157 } 176 158 void hit(LivingThing target) { … … 183 165 damage(settings.damage/settings.lifetime); 184 166 if (enemy && enemy.life!>0) enemy=null; // This enemy is ded. 185 if (!enemy) enemy=targets.getTarget(this); 186 if (!enemy && !settings.linger) { damage(life); onDeath(this); return; } // The war is over. Let's hang around. 187 float ndx, ndy; 167 if (!enemy) { 168 if (!settings.retarget) { die(); return; } 169 else { 170 enemy=targets.getTarget(this); 171 if (!enemy && !settings.linger) { die(); return; } 172 } 173 } 174 vec2f new_motion; 188 175 if (enemy) { 189 ndx=enemy.x-fx; 190 ndy=enemy.y-fy; 191 normalize(ndx, ndy, 1f-settings.aim); 176 new_motion = (enemy.pos - pos).normalized() * (1f - settings.aim); 192 177 if (auto mt=cast(MovingThing) enemy) { 193 float mx, my; mt.getMotionVector(mx, my); 194 normalize(mx, my, settings.aim); 195 ndx+=mx; ndy+=my; 178 new_motion += mt.getMotionVector().normalized() * settings.aim; 196 179 } 197 normalize(ndx, ndy, settings.speed); 198 } else ndx=ndy=0; 199 dx=dx*settings.momentum+ndx*(1f-settings.momentum); 200 dy=dy*settings.momentum+ndy*(1f-settings.momentum); 201 fx+=dx; fy+=dy; 202 x=cast(int) fx; y=cast(int) fy; 180 new_motion.length = settings.speed; 181 } else new_motion = vec2f(0f, 0f); 182 delta *= settings.momentum; delta += new_motion * (1f - settings.momentum); 183 pos += delta; 203 184 if (enemy && collide(enemy)) { hit(enemy); return; } 204 185 // if we accidentally hit one of the other targets, we settle for that. … … 284 265 } 285 266 Group!(Rocket) rockets; 286 mixin This!("settings, rsettings, targets, super(x, y, radius=12), #counter=settings.rate; #rockets=new Group!(Rocket); "); 267 mixin This!("settings, rsettings, targets, super(pos, radius=12), 268 #counter=settings.rate > 0 ? settings.rate : 1; #rockets=new Group!(Rocket);"); 287 269 void draw() { 270 auto ipos = pos.to!(int); 288 271 if (mouseOver(this)) { 289 circle( x, y, settings.range+1, White);290 circle( x, y, settings.range, Black);291 circle( x, y, settings.range-1, White);292 } 293 bufferedCircle( x, y, radius, Black, Fill=White~Green);272 circle(ipos.tuple, settings.range+1, White); 273 circle(ipos.tuple, settings.range, Black); 274 circle(ipos.tuple, settings.range-1, White); 275 } 276 bufferedCircle(ipos.tuple, radius, Black, Fill=White~Green); 294 277 rockets.draw; 295 278 } … … 302 285 if (!enemy) return; 303 286 if (counter-->0) return; 304 counter=settings.rate; 305 auto newThing=new Rocket(rsettings, targets, &die, x, y); 306 if (settings.kickstart) { 307 newThing.dx=randf-0.5; 308 newThing.dy=randf-0.5; 309 } 310 newThing.enemy=enemy; 311 rockets.addThing(newThing); newThing.update; 312 } 313 } 314 287 counter = settings.rate > 0 ? settings.rate : 1; 288 int times = 1; 289 if (settings.rate < 0) times = abs(settings.rate); 290 Range[times].each = { 291 auto newThing=new Rocket(rsettings, targets, &die, pos); 292 if (settings.kickstart) newThing.delta = vec2f.rand() / 2f; 293 newThing.enemy=enemy; 294 rockets.addThing(newThing); newThing.update; 295 }; 296 } 297 } 298 299 import SDL_ttf; 315 300 class SpawnPoint : WorldThing { 316 301 private { 317 int rate ;318 int counter;319 int life;302 int rate, counter, groupsize, group_left, breaktime, break_left; 303 float life; 304 bool break_mode; 320 305 Path path; 321 306 } 322 307 TargetGroup critters; 323 mixin This!("rate, path, super(x, y, radius=15), #counter=0; #critters=new TargetGroup; #life=10; "); 324 void draw() { bufferedCircle(x, y, radius, White, Fill=Background~Black); critters.draw; } 308 mixin This!("rate, groupsize, breaktime, life, path, super(pos, radius=15), #counter=0; 309 #group_left=groupsize; #critters=new TargetGroup; #break_mode=true; #break_left=breaktime; "); 310 void draw() { 311 bufferedCircle(pos.to!(int).tuple, radius, White, Fill=Background~Black); 312 string text; 313 if (break_mode) 314 if (critters.live) text = ".."; 315 else if (break_left) text = Format("-", break_left); 316 else text = Format("GO"); 317 else if (group_left) text = Format(group_left); 318 .print(pos.to!(int).tuple, Center, Black, text); 319 critters.draw; 320 } 325 321 void win() { throw new Exception("The critters win!"); } 326 322 static long id=0; 327 323 void update() { 328 if (counter-->0) { critters.update; return; } 329 counter+=rate; 330 life *= 1.1; 331 auto newCritter=new Critter(path, 0.6, &win, id++, &critters.removeAs!(LivingThing), x, y, 10, life); 324 critters.update; 325 if (counter > 0) { counter --; return; } 326 else counter = rate; 327 if (break_mode) { 328 if (critters.live) return; 329 else if (!break_left) 330 break_mode = false; 331 else { break_left --; return; } 332 } 333 if (!group_left) { 334 group_left = groupsize; 335 if (breaktime) { 336 break_mode = true; 337 break_left = breaktime; 338 } 339 life = life * 1.1 + 1; 340 } else group_left --; 341 // yes the last critter is intentionally stronger. 342 auto newCritter=new Critter(path, 0.6, &win, id++, &critters.removeAs!(LivingThing), pos, 10, cast(int) life); 332 343 critters.addThing(newCritter); newCritter.update; 333 critters.update;334 344 } 335 345 } … … 340 350 float count; 341 351 rgb color; 342 mixin This!("color, super(onDeath, x, y, radius=3, life=8) #count=cast(float)0; ");352 mixin This!("color, super(onDeath, pos, radius=3, life=8) #count=cast(float)0; "); 343 353 void draw() { 344 circle(x, y, cast(int)(radius+count+1), color~Yellow); 345 circle(x, y, cast(int)(radius+count), color); 354 auto ipos = pos.to!(int); 355 circle(ipos.tuple, cast(int)(radius+count+1), color~Yellow); 356 circle(ipos.tuple, cast(int)(radius+count), color); 346 357 const int lines=6; 347 358 for (int i=0; i<360; i+=360/lines) { 348 359 line( 349 cast(int)( x+sin(i*pi180)*(radius+count)), cast(int)(y+cos(i*pi180)*(radius+count)),350 cast(int)( x+sin(i*pi180)*(radius+count+4)), cast(int)(y+cos(i*pi180)*(radius+count+4)),360 cast(int)(pos.x+sin(i*pi180)*(radius+count)), cast(int)(pos.y+cos(i*pi180)*(radius+count)), 361 cast(int)(pos.x+sin(i*pi180)*(radius+count+4)), cast(int)(pos.y+cos(i*pi180)*(radius+count+4)), 351 362 color); 352 363 } … … 394 405 bool delegate(WorldThing) mouseOver; 395 406 407 import test13, tools.functional; 396 408 void main() { 397 int mousex, mousey;398 int startx, starty;bool drag=false;409 vec2f mouse_pos, start; 410 bool drag=false; 399 411 bool[int] pressed; 400 412 WorldThing[] select; 401 413 auto moveMouseOver=(WorldThing w) { 402 414 foreach (s; select) if (w is s) return true; 403 with (w) return ( .distance(x, y, mousex, mousey)<=radius);415 with (w) return ((pos - mouse_pos).length()<=radius); 404 416 }; 405 417 auto dragMouseOver=(WorldThing wt) { 406 418 if (SDLKey.LCtrl in pressed) foreach (s; select) if (wt is s) return true; 407 419 with (wt) { 408 if ( x+radius<min(startx, mousex)) return false;409 if ( x-radius>max(startx, mousex)) return false;410 if ( y+radius<min(starty, mousey)) return false;411 if ( y-radius>max(starty, mousey)) return false;420 if (pos.x+radius<min(start.x, mouse_pos.x)) return false; 421 if (pos.x-radius>max(start.x, mouse_pos.x)) return false; 422 if (pos.y+radius<min(start.y, mouse_pos.y)) return false; 423 if (pos.y-radius>max(start.y, mouse_pos.y)) return false; 412 424 } 413 425 return true; … … 419 431 Group!(Thing) group; 420 432 auto path=new Path(false, 421 Path.Point(30, 30), Path.Point(300, 30), Path.Point(300, 300), Path.Point(30, 300), Path.Point(30, 30)433 vec2f(30, 30), vec2f(300, 30), vec2f(300, 300), vec2f(30, 300), vec2f(30, 90) 422 434 ); 423 auto spawner=new SpawnPoint(64, path, 300, 400); 435 436 auto bg_surf = screen.With(screen.w, screen.h) = { 437 FatLine fl; 438 fl = new FatLine(vec2f(300, 400) ~ path.points, (float d) { 439 if (abs(d) > fl.width) return Background; 440 else if (abs(d) > fl.width - 2) return Background.blend(Black, (fl.width - abs(d)) / 2f); 441 else if (abs(d) > fl.width - 4) return Black.blend(White, (fl.width - 2 - abs(d)) / 2f); 442 else return White; 443 }, 18); 444 fl.render(); 445 }; 446 447 auto spawner=new SpawnPoint(/* rate */ 48, /* groupsize */ 10, /* breaktime */ 5, /* start life */ 64, path, vec2f(300, 400)); 424 448 group=new typeof(group)([cast(Thing)spawner]); 425 449 group.addThing(new Turret( 426 Turret.Settings(115, 1, true), 427 Rocket.Settings(/*speed*/ 1f, /*damage*/ 20, /*aim*/ 0.45, /*momentum*/0.99, /*lifetime*/1000, false, false), 428 spawner.critters, 50, 250 450 Turret.Settings(115, 2, false), 451 Rocket.Settings(/*speed*/ 1.1f, /*aim*/ 0.1, /*momentum*/0.97, /*damage*/ 1, /*lifetime*/256, /*linger*/false, /*punchthrough*/false), 452 spawner.critters, vec2f(85, 220) 453 )); 454 group.addThing(new Turret( 455 Turret.Settings(115, 2, false), 456 Rocket.Settings(/*speed*/ 1.1f, /*aim*/ 0.1, /*momentum*/0.97, /*damage*/ 1, /*lifetime*/256, false, false), 457 spawner.critters, vec2f(185, 135) 429 458 )); 430 459 group.addThing(effects); … … 438 467 update; 439 468 // addEffect!(RingEffect)(Blue~Black, mousex, mousey, 50, 50); 469 display.blit(bg_surf); 470 prettyprint(0, 0, Bottom|Right, 471 "Test .. test! [b]Bold, [i]italic and [u]underlined![/u][/i][/b] [i]Just italic now.[/i] [b][color #f00]Red?[/color][/b]Done!"); 440 472 draw; 441 473 if (drag) { 442 tintfill( min(startx, mousex), min(starty, mousey), max(startx, mousex), max(starty, mousey), Blue~White);443 line(start x, starty, mousex, mousey, Box=White);474 tintfill(start.min(mouse_pos).to!(int).tuple, start.max(mouse_pos).to!(int).tuple, Blue~White); 475 line(start.to!(int).tuple, mouse_pos.to!(int).tuple, Box=White); 444 476 } 445 477 limiter.limit({ flip; }); … … 451 483 }, (int x, int y, ubyte button, int p) { 452 484 if (!button) { 453 mouse x=x; mousey=y;485 mouse_pos.x=x; mouse_pos.y=y; 454 486 } else { 455 487 if (p==1) { 456 start x=x; starty=y;488 start.x=x; start.y=y; 457 489 mouseOver=dragMouseOver; 458 490 drag=true; … … 476 508 fps=0; 477 509 } 478 with (Background) SDL_FillRect(display.surface, null, SDL_MapRGBA(display.surface.format, values[0], values[1], values[2], 0));510 // with (Background) SDL_FillRect(display.surface, null, SDL_MapRGBA(display.surface.format, values[0], values[1], values[2], 0)); 479 511 } while (true); 480 512 } trunk/qd/qd.d
r320 r343 173 173 struct { ubyte r, g, b; } 174 174 } 175 SDL_Color toSDL() { return SDL_Color(r, g, b, 0); } 175 176 rgb opCat(rgb other) { 176 177 rgb res; … … 553 554 int height() { return display.height; } 554 555 alias width w; alias height h; 555 Area With(size_t w, size_t h, void delegate()[] dgs...) { 556 auto backup=display, backup_flags=sdl_flags, old_osc=offscreen; 557 scope(exit) { display=backup; sdl_flags=backup_flags; offscreen=old_osc; } 558 screen(w, h, 0, true); 559 foreach (dg; dgs) dg(); 560 return display; 561 } 562 void With(Area area, void delegate()[] dgs...) { 563 auto backup=display; display=area; scope(exit) display=backup; 564 auto backup_flags=sdl_flags; scope(exit) sdl_flags=backup_flags; 565 auto offs=offscreen; scope(exit) offscreen=offs; 566 foreach (dg; dgs) dg(); 556 struct WithAreaHolder(T...) { 557 T t; 558 Area opAssign(C)(lazy C callable) { 559 static if (is(T == Tuple!(Area))) { 560 auto backup=display; display=t[0]; scope(exit) display=backup; 561 auto backup_flags=sdl_flags; scope(exit) sdl_flags=backup_flags; 562 auto offs=offscreen; scope(exit) offscreen=offs; 563 } else static if (is(T == Tuple!(int, int))) { 564 auto backup=display, backup_flags=sdl_flags, old_osc=offscreen; 565 scope(exit) { display=backup; sdl_flags=backup_flags; offscreen=old_osc; } 566 screen(w, h, 0, true); 567 } else static assert(false, "opAssign with "~T.stringof~" .. ?"); 568 static if (is(C==void)) callable(); 569 else static if (is(C==void delegate())) callable()(); 570 else static assert(false, "Cannot call: "~T.stringof); 571 return display; 572 } 573 } 574 WithAreaHolder!(T) With(T...)(T t) { 575 WithAreaHolder!(T) res = void; 576 foreach (id, value; t) res.t[id] = value; 577 return res; 567 578 } 568 579 } … … 704 715 } 705 716 Area width(int w) { 706 if (w<0) return Area(br-pt(-w, height), pt(-w, size.y), surface); 707 return Area(tl, pt(w, size.y), surface); 717 if (w<0) { 718 auto new_size = pt(-w, size.y); 719 tl = br - pt(-w, height); 720 dimensions = new_size; 721 return this; 722 } else { 723 dimensions = pt(w, size.y); 724 return this; 725 } 708 726 } 709 727 //Area width(float wp) { return width(cast(int)(width*wp)); } 710 728 int width() { return dimensions.x; } 711 729 Area height(int h) { 712 if (h<0) return Area(br-pt(width, -h), pt(size.x, -h), surface); 713 return Area(tl, pt(size.x, h), surface); 730 if (h<0) { 731 auto new_size = pt(size.x, -h); 732 tl = br - pt(width, -h); 733 dimensions = new_size; 734 return this; 735 } else { 736 dimensions = pt(size.x, h); 737 return this; 738 } 714 739 } 715 740 //Area height(float hp) { return height(cast(int)(height*hp)); } … … 723 748 return Area(tl3, size, surface); 724 749 } 725 Area select(pt size, pt where, Align how) {750 Area select(pt where, pt size, Align how) { 726 751 return Area(tl+where+pt([-size.x/2, -size.x, 0][how&3], [-size.y/2, -size.y, 0][how>>2]), size, surface); 727 752 } trunk/qd/test11.d
r320 r343 18 18 Box=White, Fill=Black.blend(White, 0.1).blend(Black.blend(target, 0.9), p/50f) 19 19 ); 20 print(button, Center, Format("Hello World"));20 print(button, Center, White, Format("Hello World")); 21 21 }; 22 22 while (true) { trunk/qd/test13.d
r342 r343 1 1 module test13; 2 2 3 import qd, dglut.vector, std.stdio, tools.base, tools.log ;3 import qd, dglut.vector, std.stdio, tools.base, tools.log, std.math; 4 4 5 5 bool _polygons_overlap_4(vec2f[4] poly_1, vec2f[4] poly_2) { … … 30 30 vec2f[] pts, ds, vs; 31 31 float width; 32 this(vec2f[] pts, float w) { 32 this(vec2f[] pts, typeof(color) c, float w) { 33 color = c; 33 34 width = w; 34 35 this.pts = pts.dup; … … 74 75 } 75 76 alias normal_dist opCall; 77 rgb delegate(float) color; 78 void fill_quad(vec2f tl, vec2f br) { 79 for (int x = cast(int) tl.x; x < br.x; ++x) 80 for (int y = cast(int) tl.y; y < br.y; ++y) 81 pset(x, y, color(opCall(vec2f(x, y)))); 82 } 83 const MAXSIZE = 4; 84 void quad_descent(vec2f tl, vec2f br, float[4] dists = [float.nan, 0f, 0f, 0f]) { 85 bool maxdepth = ((br.x-tl.x) < MAXSIZE) || ((br.y-tl.y) < MAXSIZE); 86 if (isnan(dists[0])) { 87 dists[] = [opCall(tl), opCall(vec2f(br.x, tl.y)), opCall(vec2f(tl.x, br.y)), opCall(br)]; 88 } 89 void try_desc(vec2f new_tl, vec2f new_br, float[4] dists) { 90 if (!overlap(new_tl, new_br)) { 91 line(new_tl.tuple, new_br.tuple, Fill=color(dists[0])/+, Box=Blue+/); 92 return; 93 } 94 if (maxdepth) fill_quad(new_tl, new_br); 95 else quad_descent(new_tl, new_br, dists); 96 } 97 if (maxdepth) fill_quad(tl, br); 98 else { 99 auto half = (tl + br) / 2; 100 auto new_dists = [opCall(vec2f(half.x, tl.y)), opCall(vec2f(tl.x, half.y)), opCall(vec2f(br.x, half.y)), opCall(vec2f(half.x, br.y))]; 101 auto center = opCall(half); 102 try_desc(tl, half, [dists[0], new_dists[0], new_dists[1], center]); 103 try_desc(vec2f(half.x, tl.y), vec2f(br.x, half.y), [new_dists[0], dists[1], center, new_dists[2]]); 104 try_desc(vec2f(tl.x, half.y), vec2f(half.x, br.y), [new_dists[1], center, dists[2], new_dists[3]]); 105 try_desc(half, br, [center, new_dists[2], new_dists[3], dists[3]]); 106 } 107 } 108 void render() { 109 quad_descent(vec2f(0, 0), vec2f(screen.w, screen.h)); 110 } 76 111 } 77 112 … … 86 121 } 87 122 88 import tools.functional, std.math, tools.mersenne;123 /*import tools.functional, std.math, tools.mersenne; 89 124 void main() { 90 125 screen(1024, 768); … … 108 143 else return White; 109 144 } 110 void fill_quad(vec2f tl, vec2f br) {111 for (int x = cast(int) tl.x; x < br.x; ++x)112 for (int y = cast(int) tl.y; y < br.y; ++y)113 pset(x, y, color(df(vec2f(x, y))));114 }115 const MAXSIZE = 4;116 void quad_descent(vec2f tl, vec2f br, float[4] dists = [float.nan, 0f, 0f, 0f]) {117 bool maxdepth = ((br.x-tl.x) < MAXSIZE) || ((br.y-tl.y) < MAXSIZE);118 if (isnan(dists[0])) {119 dists[] = [df(tl), df(vec2f(br.x, tl.y)), df(vec2f(tl.x, br.y)), df(br)];120 }121 void try_desc(vec2f new_tl, vec2f new_br, float[4] dists) {122 if (!df.overlap(new_tl, new_br)) {123 line(new_tl.tuple, new_br.tuple, Fill=color(dists[0])/*, Box=Blue*/);124 return;125 }126 if (maxdepth) fill_quad(new_tl, new_br);127 else quad_descent(new_tl, new_br, dists);128 }129 if (maxdepth) fill_quad(tl, br);130 else {131 auto half = (tl + br) / 2;132 auto new_dists = [df(vec2f(half.x, tl.y)), df(vec2f(tl.x, half.y)), df(vec2f(br.x, half.y)), df(vec2f(half.x, br.y))];133 auto center = df(half);134 try_desc(tl, half, [dists[0], new_dists[0], new_dists[1], center]);135 try_desc(vec2f(half.x, tl.y), vec2f(br.x, half.y), [new_dists[0], dists[1], center, new_dists[2]]);136 try_desc(vec2f(tl.x, half.y), vec2f(half.x, br.y), [new_dists[1], center, dists[2], new_dists[3]]);137 try_desc(half, br, [center, new_dists[2], new_dists[3], dists[3]]);138 }139 }140 145 while (true) { 141 146 quad_descent(vec2f(0, 0), vec2f(screen.w, screen.h)); … … 147 152 } 148 153 } 154 */ trunk/qd/test2.d
r316 r343 26 26 class Primitives { 27 27 void drawFrame(ref Area orig) { 28 with (orig) screen.With(orig , line(0, 0, (size-pt(1, 1)).tupleof, Box=White));28 with (orig) screen.With(orig) = line(0, 0, (size-pt(1, 1)).tupleof, Box=White); 29 29 orig=orig.shrink(1); 30 30 } … … 201 201 logln("render proc - temp=", temp); 202 202 assert(drawthr.runsMe()); 203 size_t aa= 3;203 size_t aa=1; 204 204 float scale = 255f / (aa*aa); 205 205 size_t cc=0; … … 260 260 void area(Area target) { 261 261 if (target && (!myArea || target.dimensions!=myArea.dimensions)) { 262 temp = screen.With(target.width, target.height , cls);262 temp = screen.With(target.width, target.height) = cls; 263 263 } 264 264 super.area=target; … … 498 498 class TextBox : Text { 499 499 this(string s, Align alignment=Left|Top) { super(s, alignment); } 500 void draw() { screen.With(myArea , cls); super.draw(); }500 void draw() { screen.With(myArea) = cls; super.draw(); } 501 501 } 502 502
