Changeset 345

Show
Ignore:
Timestamp:
05/30/08 04:27:11 (6 months ago)
Author:
FeepingCreature
Message:
  • Formatting prettyprint support
  • Area's opIn support for vectors
  • Blurred circle filter support (alpha)
  • Free font surfaces after blitting
  • dt: life displays now fit in bubbles
  • dt: age -> color
  • dt: renamed rocket to ammo
  • dt: rockets now have separate direction and speed.
  • dt: limiter debugging code commented out
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/qd/SDL_ttf.d

    r343 r345  
    99} 
    1010 
    11 import std.string: toStringz, toString
     11import std.string: toStringz, toString, atoi
    1212import std.file: read; 
    1313import tools.base; 
     
    7575      if (color.length == 3) color = color[0]~"0"~color[1]~"0"~color[2]~"0"; 
    7676      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") 
     77      push(pre, "color", (ref fontsettings fs) { fs.color = res; }); 
     78    }, "[/color]": close_tag("color"), 
     79    "[size ": (string pre, ref string post) { 
     80      int dir; 
     81      if (post[0] == '+') dir = 1; 
     82      else if (post[0] == '-') dir = -1; 
     83      if (post[0] == '+' /or/ '-') post = post[1 .. $]; 
     84      string s; ptuple(s, post) = post.splitAt("]"); 
     85      auto n = s.atoi(); 
     86      push(pre, "size", (ref fontsettings fs) { 
     87        if (!dir) fs.size = n; 
     88        else fs.size += n * dir; 
     89      }); 
     90    }, "[/size]": close_tag("size") 
    7991  ]; 
    8092  text.glomp_parse(tags, (string s) { 
     
    89101  } body { 
    90102  auto surfs = new Area[strings.length]; 
     103  scope(exit) foreach (surf; surfs) SDL_FreeSurface(surf.surface); 
    91104  int width, height; 
    92105  foreach (i, str; strings) { 
     
    106119 
    107120void print(int x, int y, Align how, rgb col, string what) { 
    108   if (!(14 in standard)) initFont(); 
    109121  fontsettings foo; foo.color = col; 
    110   auto surf=standard[14].render(what, foo); 
    111   display.select(surf.size, pt(x, y), how).blit(surf); 
    112   SDL_FreeSurface(surf.surface); 
     122  print(x, y, how, [foo], [what]); 
    113123} 
    114124 
     
    156166    auto res=_render(text, s); 
    157167    if (!res) throw new Exception("Couldn't render "~'"'~text~'"'~": "~.toString(SDL_GetError)); 
    158     return Area(pt(0, 0), pt(res.w, res.h), res); 
     168    return Area(res); 
    159169  } 
    160170  void[] file_buffer; 
  • trunk/qd/dt.d

    r343 r345  
    2828class LivingThing : WorldThing { 
    2929  private { 
    30     int life
     30    int life, age
    3131    void delegate(LivingThing) onDeath; 
    3232  } 
     33  override void update() { age++; } 
    3334  void damage(int howmuch) { life-=howmuch; if (life!>0) onDeath(this); } 
    3435  void die() { damage(life); onDeath(this); } 
     
    111112    bufferedCircle(pos.to!(int).tuple, radius, Black, Fill=Blue~White~White); 
    112113    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    string fmt; 
     115    if (life>1000) fmt = Format("[size -5]", life, "[/size]"); 
     116    else if (life > 100) fmt = Format("[size -3]", life, "[/size]"); 
     117    else fmt = Format(life); 
     118    fmt = "[color #040]"~fmt~"[/color]"; 
     119    .prettyprint(pos.to!(int).tuple, Center, fmt); 
    114120  } 
    115121  override vec2f getMotionVector() { return train.delta; } 
     
    136142} 
    137143 
    138 class Rocket : LivingThing { 
     144class Ammo : LivingThing { 
    139145  TargetGroup targets; 
    140   vec2f delta; 
     146  // vec2f delta; 
     147  float length, angle; 
    141148  struct Settings { 
    142     float speed, aim, momentum; 
     149    float speed, aim, speed_momentum, dir_momentum; 
    143150    int damage, lifetime; 
    144151    bool linger, punchthrough, retarget; 
     
    146153  Settings settings; 
    147154  mixin This!("settings, targets, super(onDeath, pos, radius=3, life=10) 
    148     #life=settings.damage; #delta=vec2f(0); "); 
     155    #life=settings.damage; #angle=0f; "); 
    149156  LivingThing enemy; 
    150157  void draw() { 
    151158    //line(x, y, enemy.x, enemy.y, White); 
    152     bufferedCircle(pos.to!(int).tuple, radius, Fill=Black); 
     159    auto color = Black.blend(White, age * 1f / settings.lifetime); 
     160    bufferedCircle(pos.to!(int).tuple, radius, Fill=color, color); 
    153161  } 
    154162  void damage(typeof(life) d) { 
     163    int prelife = life; 
    155164    super.damage(d); 
    156     if (life!>0) addEffect!(RingEffect)(Red, pos, 3, 3); 
     165    if (life!>0) addEffect!(RingEffect)(Red, pos, 3, cast(int) (log(prelife) + PI_2)); // I WANNA PIE TOO 
    157166  } 
    158167  void hit(LivingThing target) { 
     
    163172  } 
    164173  void update() { 
    165     damage(settings.damage/settings.lifetime); 
     174    if (!(pos in display)) die(); 
     175    super.update(); 
     176    if (age > settings.lifetime) die(); 
    166177    if (enemy && enemy.life!>0) enemy=null; // This enemy is ded. 
    167178    if (!enemy) { 
    168       if (!settings.retarget) { die(); return; } 
    169       else { 
     179      if (settings.retarget) { 
    170180        enemy=targets.getTarget(this); 
    171         if (!enemy && !settings.linger) { die(); return;
    172      
     181     
     182      if (!enemy && !settings.linger) { die(); return;
    173183    } 
    174184    vec2f new_motion; 
     185    vec2f delta() { 
     186      auto res = vec2f(1, 0); 
     187      res.rotate(angle); res.length = length; 
     188      return res; 
     189    } 
    175190    if (enemy) { 
    176191      new_motion = (enemy.pos - pos).normalized() * (1f - settings.aim); 
     
    179194      } 
    180195      new_motion.length = settings.speed; 
    181     } else new_motion = vec2f(0f, 0f); 
    182     delta *= settings.momentum; delta += new_motion * (1f - settings.momentum); 
     196       
     197      auto old_motion = delta(); 
     198      //logln("old_motion: ", old_motion, ", angle ", angle, ", length ", length); 
     199      //logln("new_motion: ", new_motion, ", their angle ", old_motion.angle(new_motion)); 
     200      auto d_angle = old_motion.angle(new_motion) * (1f - settings.dir_momentum); 
     201      if (isnan(length)) { 
     202        d_angle = vec2f(1, 0).angle(new_motion); 
     203        length = 0f; 
     204      } 
     205      //logln("d_angle: ", d_angle); 
     206      angle += d_angle; 
     207       
     208      length = length * settings.speed_momentum + new_motion.length * (1f - settings.speed_momentum); 
     209    } 
    183210    pos += delta; 
    184211    if (enemy && collide(enemy)) { hit(enemy); return; } 
     
    259286  } 
    260287  Settings settings; 
    261   Rocket.Settings rsettings; 
     288  Ammo.Settings rsettings; 
    262289  private { 
    263290    int counter; 
    264291    TargetGroup targets; 
    265292  } 
    266   Group!(Rocket) rockets
     293  Group!(Ammo) Teh_Ordnance
    267294  mixin This!("settings, rsettings, targets, super(pos, radius=12), 
    268     #counter=settings.rate > 0 ? settings.rate : 1; #rockets=new Group!(Rocket);"); 
     295    #counter=settings.rate > 0 ? settings.rate : 1; #Teh_Ordnance=new Group!(Ammo);"); 
    269296  void draw() { 
    270297    auto ipos = pos.to!(int); 
     
    275302    } 
    276303    bufferedCircle(ipos.tuple, radius, Black, Fill=White~Green); 
    277     rockets.draw; 
     304    Teh_Ordnance.draw; 
    278305  } 
    279306  private void die(LivingThing not_so_living_now_are_you) { 
    280     rockets.remove(cast(Rocket)cast(void*)not_so_living_now_are_you); // trust me. this is correct. 
     307    Teh_Ordnance.remove(cast(Ammo)cast(void*)not_so_living_now_are_you); // trust me. this is correct. 
    281308  } 
    282309  void update() { 
    283     scope(exit) rockets.update; 
     310    scope(exit) Teh_Ordnance.update; 
    284311    auto enemy=targets.getTarget(this, settings.range); 
    285312    if (!enemy) return; 
     
    289316    if (settings.rate < 0) times = abs(settings.rate); 
    290317    Range[times].each = { 
    291       auto newThing=new Rocket(rsettings, targets, &die, pos); 
    292       if (settings.kickstart) newThing.delta = vec2f.rand() / 2f; 
     318      auto newThing=new Ammo(rsettings, targets, &die, pos); 
     319      if (settings.kickstart) { 
     320        with (vec2f.rand()) { 
     321          newThing.angle = angle(vec2f(1, 0)); 
     322          newThing.length = length(); 
     323        } 
     324      } 
    293325      newThing.enemy=enemy; 
    294       rockets.addThing(newThing); newThing.update; 
     326      Teh_Ordnance.addThing(newThing); newThing.update; 
    295327    }; 
    296328  } 
     329} 
     330 
     331void withSet(T)(ref T var, T val, void delegate() dg) { 
     332  auto backup = var; var = val; 
     333  scope(exit) var = backup; 
     334  dg(); 
    297335} 
    298336 
     
    309347    #group_left=groupsize; #critters=new TargetGroup; #break_mode=true; #break_left=breaktime; "); 
    310348  void draw() { 
    311     bufferedCircle(pos.to!(int).tuple, radius, White, Fill=Background~Black); 
    312349    string text; 
    313350    if (break_mode) 
     
    316353      else text = Format("GO"); 
    317354    else if (group_left) text = Format(group_left); 
     355    critters.draw; 
     356    withSet(alpha, 64, { circle(pos.to!(int).tuple, radius, White, Fill=Background~Black); }); 
    318357    .print(pos.to!(int).tuple, Center, Black, text); 
    319     critters.draw; 
    320358  } 
    321359  void win() { throw new Exception("The critters win!"); } 
     
    392430      flip(); 
    393431      pc.stop; 
    394       writefln("Flipped - took ", pc.milliseconds, "ms!"); 
     432      //writefln("Flipped - took ", pc.milliseconds, "ms!"); 
    395433      cur=SDL_GetTicks(); 
    396434    } 
    397435    scope(exit) count=cur; 
    398436    if (fps && (cur-count<ms)) { 
    399       writefln("Delay ", ms-(cur-count)); 
     437      //writefln("Delay ", ms-(cur-count)); 
    400438      SDL_Delay(ms-(cur-count)); 
    401     } else writefln("No delay - ", (cur-count)-ms, " over!"); 
     439    } //else writefln("No delay - ", (cur-count)-ms, " over!"); 
    402440  } 
    403441} 
     
    448486  group=new typeof(group)([cast(Thing)spawner]); 
    449487  group.addThing(new Turret( 
    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), 
     488    Turret.Settings(115, 24, false), 
     489    Ammo.Settings(/*speed*/ 1.5f, /*aim*/ 0.25, /*momentum_speed*/0, /*momentum_dir*/ 1, /*damage*/ 8, /*lifetime*/256, /*linger*/true, /*punchthrough*/false), 
    452490    spawner.critters, vec2f(85, 220) 
    453491  )); 
    454492  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), 
     493    Turret.Settings(115, 6, true), 
     494    Ammo.Settings(/*speed*/ 0.9f, /*aim*/ 0, /*momentum_speed*/0.9, /*momentum_dir*/ 0.98, /*damage*/ 2, /*lifetime*/1024, true, false, true), 
    457495    spawner.critters, vec2f(185, 135) 
    458496  )); 
     
    469507    display.blit(bg_surf); 
    470508    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!"); 
     509      "Test .. [size -1]test![/size] [b]Bold, [i]italic and [u]underlined![/u][/i][/b] [i]Just italic now.[/i] [b][color #f00]Red?[/color][/b]Done!"); 
    472510    draw; 
    473511    if (drag) { 
     
    503541      writefln(fps, " FPS"); 
    504542      ulong rcount=0; 
    505       foreach (entry; group) if (auto t=cast(Turret) entry) rcount+=t.rockets.length; 
    506       writefln(rcount, " rockets"); 
     543      foreach (entry; group) if (auto t=cast(Turret) entry) rcount+=t.Teh_Ordnance.length; 
     544      writefln(rcount, " explody thingies"); 
    507545      avg+=fps; ++count; 
    508546      fps=0; 
  • trunk/qd/qd.d

    r343 r345  
    217217} 
    218218 
     219int alpha; 
     220 
    219221void putpixel(int x, int y, uint col) { 
    220222  auto transformed=display.tl+pt(x, y); 
     
    370372template UnPoint(T...) { mixin _UnPoint!(0, T); } 
    371373 
     374static import std.math; 
     375bool hasnan(T...)(T t) { 
     376  foreach (value; t) 
     377    static if (is(typeof(value): real)) if (std.math.isnan(cast(real) value)) return true; 
     378  return false; 
     379} 
     380 
    372381void line(_T...)(_T _p) { 
     382  if (hasnan(_p)) return; 
    373383  alias UnPoint!(_T).tuple T; 
    374384  auto p = mixin("stuple("~Replace!(UnPoint!(_T).value, "%", "_p")~")"); 
     
    457467} 
    458468 
    459 void hline(int x, int y, int w, uint col) { for (int pos=x; pos<=x+w; ++pos) putpixel(pos, y, col); } 
     469void hline(int x, int y, int w, uint col) { 
     470  if (alpha) { 
     471    ubyte[4] cur_col; 
     472    auto color = (cast(ubyte*) &col)[0..4]; // this was originally an error, but it's an awesome graphics effect. 
     473    for (int pos=x; pos<=x+w; ++pos) { 
     474      getpixel32(display.surface, pos, y, &cur_col); 
     475      color[0]=cast(ubyte)((cur_col[0]*alpha+color[0]*(255-alpha))>>8); 
     476      color[1]=cast(ubyte)((cur_col[1]*alpha+color[1]*(255-alpha))>>8); 
     477      color[2]=cast(ubyte)((cur_col[2]*alpha+color[2]*(255-alpha))>>8); 
     478      putpixel32(display.surface, pos, y, SDL_MapRGBA(display.surface.format, color[0], color[1], color[2], color[3])); 
     479    } 
     480  } else { 
     481    for (int pos=x; pos<=x+w; ++pos) putpixel(pos, y, col); 
     482  } 
     483
    460484 
    461485import std.stdio; 
     
    699723    return res; 
    700724  } 
    701   bool opIn_r(pt p) { return (p.x>=tl.x && p.x<=(tl.x+size.x)) && (p.y>=tl.y && p.y<=(tl.y+size.y)); } 
     725  bool opIn_r(T)(T vt) { return (vt.x>=tl.x && vt.x<=(tl.x+size.x)) && (vt.y>=tl.y && vt.y<=(tl.y+size.y)); } 
    702726  Area select(int x, int y, int w=int.max, int h=int.max) { 
    703727    if (w==int.max) w=size.x;