Description: port to D language version 2
  With this patch the code is accapted by gdc-4.6 0.29.1-4.6.4-3 without
  triggering deprecated feature warnings/errors.
Author: Peter De Wachter <pdewacht@gmail.com>

--- a/src/abagames/mcd/barrage.d
+++ b/src/abagames/mcd/barrage.d
@@ -33,7 +33,7 @@
     parserParam ~= new ParserParam(p, rank, speed);
   }
 
-  public void addBml(char[] bmlDirName, char[] bmlFileName, float rank, float speed) {
+  public void addBml(string bmlDirName, string bmlFileName, float rank, float speed) {
     BulletMLParser *p = BarrageManager.getInstance(bmlDirName, bmlFileName);
     if (!p)
       throw new Error("File not found: " ~ bmlDirName ~ "/" ~ bmlFileName);
@@ -57,24 +57,26 @@
  */
 public class BarrageManager {
  private:
-  static BulletMLParserTinyXML *parser[char[]][char[]];
-  static const char[] BARRAGE_DIR_NAME = "/usr/share/games/mu-cade/barrage";
+  static BulletMLParserTinyXML *parser[string][string];
+  static const string BARRAGE_DIR_NAME = "/usr/share/games/mu-cade/barrage";
 
   public static void load() {
-    char[][] dirs = listdir(BARRAGE_DIR_NAME);
-    foreach (char[] dirName; dirs) {
+    auto dirs = dirEntries(BARRAGE_DIR_NAME, SpanMode.shallow);
+    foreach (string fullDirName; dirs) {
+      string dirName = baseName(fullDirName);
       parser[dirName] = null;
-      char[][] files = listdir(BARRAGE_DIR_NAME ~ "/" ~ dirName);
-      foreach (char[] fileName; files) {
-        if (getExt(fileName) != "xml")
+      auto files = dirEntries(fullDirName, SpanMode.shallow);
+      foreach (string fullFileName; files) {
+        string fileName = baseName(fullFileName);
+        if (extension(fileName) != ".xml")
           continue;
         parser[dirName][fileName] = loadInstance(dirName, fileName);
       }
     }
   }
 
-  private static BulletMLParserTinyXML* loadInstance(char[] dirName, char[] fileName) {
-    char[] barrageName = dirName ~ "/" ~ fileName;
+  private static BulletMLParserTinyXML* loadInstance(string dirName, string fileName) {
+    string barrageName = dirName ~ "/" ~ fileName;
     Logger.info("Load BulletML: " ~ barrageName);
     parser[dirName][fileName] = 
       BulletMLParserTinyXML_new(std.string.toStringz(BARRAGE_DIR_NAME ~ "/" ~ barrageName));
@@ -82,11 +84,11 @@
     return parser[dirName][fileName];
   }
 
-  public static BulletMLParserTinyXML* getInstance(char[] dirName, char[] fileName) {
+  public static BulletMLParserTinyXML* getInstance(string dirName, string fileName) {
     return parser[dirName][fileName];
   }
 
-  public static BulletMLParserTinyXML*[] getInstanceList(char[] dirName) {
+  public static BulletMLParserTinyXML*[] getInstanceList(string dirName) {
     BulletMLParserTinyXML *pl[];
     foreach (BulletMLParserTinyXML *p; parser[dirName]) {
       pl ~= p;
@@ -95,7 +97,7 @@
   }
 
   public static void unload() {
-    foreach (BulletMLParserTinyXML *pa[char[]]; parser) {
+    foreach (BulletMLParserTinyXML *pa[string]; parser) {
       foreach (BulletMLParserTinyXML *p; pa) {
         BulletMLParserTinyXML_delete(p);
       }
--- a/src/abagames/mcd/boot.d
+++ b/src/abagames/mcd/boot.d
@@ -6,6 +6,7 @@
 module abagames.mcd.boot;
 
 private import std.string;
+private import std.conv;
 private import std.stream;
 private import std.math;
 private import std.c.stdlib;
@@ -52,10 +53,10 @@
       _moduleCtor();
       char exe[4096];
       GetModuleFileNameA(null, exe, 4096);
-      char[][1] prog;
-      prog[0] = std.string.toString(exe);
-      result = boot(prog ~ std.string.split(std.string.toString(lpCmdLine)));
-    } catch (Object o) {
+      string[1] prog;
+      prog[0] = to!string(exe);
+      result = boot(prog ~ std.string.split(to!string(lpCmdLine)));
+    } catch (Throwable o) {
       Logger.error("Exception: " ~ o.toString());
       result = EXIT_FAILURE;
     }
@@ -64,12 +65,12 @@
   }
 } else {
   // Boot as the general executable.
-  public int main(char[][] args) {
+  public int main(string[] args) {
     return boot(args);
   }
 }
 
-public int boot(char[][] args) {
+public int boot(string[] args) {
   screen = new Screen;
   input = new RecordableTwinStickPad;
   gameManager = new GameManager;
@@ -84,11 +85,11 @@
   return EXIT_SUCCESS;
 }
 
-private void parseArgs(char[][] commandArgs, Screen screen) {
-  char[][] args = readOptionsIniFile();
+private void parseArgs(string[] commandArgs, Screen screen) {
+  string[] args = readOptionsIniFile();
   for (int i = 1; i < commandArgs.length; i++)
     args ~= commandArgs[i];
-  char[] progName = commandArgs[0];
+  string progName = commandArgs[0];
   for (int i = 0; i < args.length; i++) {
     switch (args[i]) {
     case "-brightness":
@@ -97,7 +98,7 @@
         throw new Exception("Invalid options");
       }
       i++;
-      float b = cast(float) std.string.atoi(args[i]) / 100;
+      float b = cast(float) to!int(args[i]) / 100;
       if (b < 0 || b > 1) {
         usage(args[0]);
         throw new Exception("Invalid options");
@@ -116,9 +117,9 @@
         throw new Exception("Invalid options");
       }
       i++;
-      int w = std.string.atoi(args[i]);
+      int w = to!int(args[i]);
       i++;
-      int h = std.string.atoi(args[i]);
+      int h = to!int(args[i]);
       screen.width = w;
       screen.height = h;
       break;
@@ -135,7 +136,7 @@
         throw new Exception("Invalid options");
       }
       i++;
-      TwinStickPad.rotate = cast(float) std.string.atoi(args[i]) * PI / 180.0f;
+      TwinStickPad.rotate = cast(float) to!int(args[i]) * PI / 180.0f;
       break;
     case "-reversestick2":
     case "-reverserightstick":
@@ -157,17 +158,17 @@
   }
 }
 
-private final const char[] OPTIONS_INI_FILE = "options.ini";
+private const string OPTIONS_INI_FILE = "options.ini";
 
-private char[][] readOptionsIniFile() {
+private string[] readOptionsIniFile() {
   try {
     return Tokenizer.readFile(OPTIONS_INI_FILE, " ");
-  } catch (Object e) {
+  } catch (Throwable e) {
     return null;
   }
 }
 
-private void usage(char[] progName) {
+private void usage(string progName) {
   Logger.error
     ("Usage: " ~ progName ~ " [-window] [-res x y] [-brightness [0-100]] [-nosound] [-exchange] [-rotatestick2 deg] [-reversestick2] [-disablestick2] [-enableaxis5]");
 }
--- a/src/abagames/mcd/bullet.d
+++ b/src/abagames/mcd/bullet.d
@@ -52,7 +52,7 @@
   ShapeGroup shape;
   LinePoint linePoint;
 
-  invariant {
+  invariant() {
     if (bullet && bullet.pos) {
       assert(bullet.pos.x <>= 0);
       assert(bullet.pos.y <>= 0);
@@ -184,7 +184,7 @@
       removeForced();
   }
 
-  public void draw() {
+  public override void draw() {
   }
 
   public void slowdown() {
@@ -215,7 +215,7 @@
   LinePoint linePoint;
   int cnt;
 
-  invariant {
+  invariant() {
     if (pos) {
       assert(pos.x <>= 0);
       assert(pos.y <>= 0);
@@ -296,7 +296,7 @@
     }
   }
 
-  public override void collide(OdeActor actor, inout bool hasCollision, inout bool checkFeedback) {
+  public override void collide(OdeActor actor, ref bool hasCollision, ref bool checkFeedback) {
     hasCollision = checkFeedback = false;
     Enemy e = cast(Enemy) actor;
     if (cast(Ship) actor || cast(ShipTail) actor || (e && e.collideBullet)) {
@@ -351,7 +351,7 @@
     shape.drawShadow(linePoint);
   }
 
-  public void draw() {
+  public override void draw() {
     if (removeCnt > 0)
       return;
     linePoint.draw();
--- a/src/abagames/mcd/bulletimpl.d
+++ b/src/abagames/mcd/bulletimpl.d
@@ -89,7 +89,7 @@
   float rank;
   float speed;
 
-  invariant {
+  invariant() {
     assert(rank >= 0 && rank <= 1);
     assert(speed > 0 && speed < 10);
   }
--- a/src/abagames/mcd/enemy.d
+++ b/src/abagames/mcd/enemy.d
@@ -43,7 +43,7 @@
   EnemyState state;
   Vector3 lastForce;
 
-  invariant {
+  invariant() {
     if (state && state.pos) {
       assert(state.pos.x <>= 0);
       assert(state.pos.y <>= 0);
@@ -64,7 +64,7 @@
     rand.setSeed(seed);
   }
 
-  public void init(Object[] args) {
+  public override void init(Object[] args) {
     super.init(true);
     field = cast(Field) args[0];
     particles = cast(ParticlePool) args[1];
@@ -126,7 +126,7 @@
     state.joints = joints;
   }
 
-  public void move() {
+  public override void move() {
     if (checkDestroyed())
       return;
     updateState();
@@ -143,7 +143,7 @@
     spec.recordLinePoints(state, state.linePoint);
   }
 
-  public void remove() {
+  public override void remove() {
     removeCleaning();
     super.remove();
   }
@@ -202,7 +202,7 @@
     }
   }
 
-  public override void collide(OdeActor actor, inout bool hasCollision, inout bool checkFeedback) {
+  public override void collide(OdeActor actor, ref bool hasCollision, ref bool checkFeedback) {
     hasCollision = checkFeedback = false;
     if (!exists)
       return;
@@ -311,7 +311,7 @@
     spec.drawShadow(state.linePoint);
   }
 
-  public void draw() {
+  public override void draw() {
     state.linePoint.draw();
     spec.drawSubShape(state);
   }
@@ -422,7 +422,7 @@
   static const int MAX_LINE_POINT_NUM = 24;
   Field field;
 
-  invariant {
+  invariant() {
     assert(pos.x <>= 0);
     assert(pos.y <>= 0);
     assert(pos.z <>= 0);
@@ -537,7 +537,7 @@
   public void recordLinePoints(EnemyState state, LinePoint lp) {
     glPushMatrix();
     Screen.glTranslate(state.pos);
-    glMultMatrixd(state.rot);
+    glMultMatrixd(state.rot.ptr);
     glScalef(state.sizeScale.x, state.sizeScale.y, state.sizeScale.z);
     lp.beginRecord();
     shape.recordLinePoints(lp);
--- a/src/abagames/mcd/field.d
+++ b/src/abagames/mcd/field.d
@@ -42,7 +42,7 @@
   Texture _titleTexture;
   int cnt;
 
-  invariant {
+  invariant() {
     if(eyePos) {
       assert(eyePos.x < 100 && eyePos.x > -100);
       assert(eyePos.y < 100 && eyePos.y > -100);
@@ -294,7 +294,7 @@
     return (_size.contains(p.x, p.y) && fabs(p.z) < 1);
   }
 
-  public Vector size() {
+  public const(Vector) size() const {
     return _size;
   }
 
--- a/src/abagames/mcd/gamemanager.d
+++ b/src/abagames/mcd/gamemanager.d
@@ -38,7 +38,7 @@
  */
 public class GameManager: abagames.util.sdl.gamemanager.GameManager {
  private:
-  static const char[] LAST_REPLAY_FILE_NAME = "last.rpl";
+  static const string LAST_REPLAY_FILE_NAME = "last.rpl";
   static const int RANK_DOWN_INTERVAL = 60 * 1000;
   static const int BGM_CHANGE_INTERVAL = 2 * 60 * 1000;
   static const enum GameState {
@@ -227,7 +227,7 @@
     ship.clearContactJoint();
     enemies.move();
     bullets.move();
-    switch (state) {
+    switch (state) { default: break;
     case GameState.IN_GAME:
     case GameState.REPLAY:
       ship.move();
@@ -404,7 +404,7 @@
   public void drawState() {
     Letter.drawNum(score, 120, 21, 6);
     Letter.drawTime(time, 610, 30, 6);
-    switch (state) {
+    switch (state) { default: break;
     case GameState.IN_GAME:
     case GameState.REPLAY:
       if (left > 0) {
@@ -442,22 +442,22 @@
   private void saveLastReplay() {
     try {
       saveReplay(LAST_REPLAY_FILE_NAME);
-    } catch (Object o) {}
+    } catch (Throwable o) {}
   }
 
   private void loadLastReplay() {
     try {
       loadReplay(LAST_REPLAY_FILE_NAME);
-    } catch (Object o) {
+    } catch (Throwable o) {
       resetReplay();
     }
   }
 
-  private void saveReplay(char[] fileName) {
+  private void saveReplay(string fileName) {
     _replayData.save(fileName);
   }
 
-  private void loadReplay(char[] fileName) {
+  private void loadReplay(string fileName) {
     _replayData = new ReplayData;
     _replayData.load(fileName);
   }
--- a/src/abagames/mcd/letter.d
+++ b/src/abagames/mcd/letter.d
@@ -107,7 +107,7 @@
     return idx;
   }
 
-  public static void drawString(char[] str, float lx, float y, float s,
+  public static void drawString(string str, float lx, float y, float s,
                                 int d = Direction.TO_RIGHT,
                                 bool rev = false, float od = 0) {
     lx += LETTER_WIDTH * s / 2;
@@ -115,7 +115,7 @@
     float x = lx;
     int idx;
     float ld;
-    switch (d) {
+    switch (d) { default: break;
     case Direction.TO_RIGHT:
       ld = 0;
       break;
@@ -139,7 +139,7 @@
           drawLetter(idx, x, y, s, ld);
       }
       if (od == 0) {
-        switch(d) {
+        switch(d) { default: break;
         case Direction.TO_RIGHT:
           x += s * LETTER_WIDTH;
           break;
--- a/src/abagames/mcd/particle.d
+++ b/src/abagames/mcd/particle.d
@@ -35,7 +35,7 @@
   float decayRatio;
   LinePoint linePoint;
 
-  invariant {
+  invariant() {
     if (pos) {
       assert(pos.x <>= 0);
       assert(pos.y <>= 0);
@@ -171,7 +171,7 @@
   ConnectedParticle prevParticle;
   LinePoint linePoint;
 
-  invariant {
+  invariant() {
     if (_pos) {
       assert(_pos.x <>= 0);
       assert(_pos.y <>= 0);
@@ -286,7 +286,7 @@
     glPushMatrix();
     Screen.glTranslate(_pos);
     if (enableRotate)
-      glMultMatrixd(rot);
+      glMultMatrixd(rot.ptr);
     linePoint.beginRecord();
     linePoint.record(0, 0, 0);
     linePoint.record((prevParticle.pos.x - _pos.x) * 2,
@@ -358,7 +358,7 @@
   ShapeGroup shape;
   LinePoint linePoint;
 
-  invariant {
+  invariant() {
     if (pos) {
       assert(pos.x <>= 0);
       assert(pos.y <>= 0);
@@ -483,7 +483,7 @@
   float size;
   int cnt;
 
-  invariant {
+  invariant() {
     if (pos) {
       assert(pos.x <>= 0);
       assert(pos.y <>= 0);
@@ -542,7 +542,7 @@
   int cnt;
   int num1, num2;
 
-  invariant {
+  invariant() {
     if (pos) {
       assert(pos.x <>= 0);
       assert(pos.y <>= 0);
--- a/src/abagames/mcd/prefmanager.d
+++ b/src/abagames/mcd/prefmanager.d
@@ -7,6 +7,7 @@
 
 private import std.stream;
 private import std.string;
+private import std.conv;
 private import std.file;
 private import std.c.stdlib;
 private import abagames.util.prefmanager;
@@ -17,18 +18,18 @@
 public class PrefManager: abagames.util.prefmanager.PrefManager {
  private:
   static const int VERSION_NUM = 10;
-  static const char[] PREF_FILE_NAME = "mcd.prf";
+  static const string PREF_FILE_NAME = "mcd.prf";
   PrefData _prefData;
 
   public this() {
     _prefData = new PrefData;
   }
 
-  public static char[] pref_dir() {
-    char * home = getenv("HOME");
+  public static string pref_dir() {
+    const(char)* home = getenv("HOME");
     if (home is null)
       throw new Error("HOME environment variable undefined");
-    char[] dir = std.string.toString(home) ~ "/.mu-cade";
+    string dir = to!string(home) ~ "/.mu-cade";
     try {
       mkdir(dir);
     } catch (FileException e) {
@@ -37,7 +38,7 @@
   }
 
   public void load() {
-    auto File fd = new File;
+    scope File fd = new File;
     try {
       int ver;
       fd.open(pref_dir() ~ "/" ~ PREF_FILE_NAME);
@@ -46,7 +47,7 @@
         throw new Error("Wrong version num");
       else
         _prefData.load(fd);
-    } catch (Object e) {
+    } catch (Throwable e) {
       _prefData.init();
     } finally {
       if (fd.isOpen())
@@ -55,7 +56,7 @@
   }
 
   public void save() {
-    auto File fd = new File;
+    scope File fd = new File;
     fd.create(pref_dir ~ "/" ~ PREF_FILE_NAME);
     fd.write(VERSION_NUM);
     _prefData.save(fd);
--- a/src/abagames/mcd/replay.d
+++ b/src/abagames/mcd/replay.d
@@ -23,8 +23,8 @@
   int time = 0;
  private:
 
-  public void save(char[] fileName) {
-    auto File fd = new File;
+  public void save(string fileName) {
+    scope File fd = new File;
     fd.create(PrefManager.pref_dir() ~ "/" ~ fileName);
     fd.write(VERSION_NUM);
     fd.write(seed);
@@ -34,8 +34,8 @@
     fd.close();
   }
 
-  public void load(char[] fileName) {
-    auto File fd = new File;
+  public void load(string fileName) {
+    scope File fd = new File;
     fd.open(PrefManager.pref_dir() ~ "/" ~ fileName);
     int ver;
     fd.read(ver);
--- a/src/abagames/mcd/screen.d
+++ b/src/abagames/mcd/screen.d
@@ -15,10 +15,10 @@
  */
 public class Screen: Screen3D {
  private:
-  const char[] CAPTION = "Mu-cade";
+  const string CAPTION = "Mu-cade";
   Field field;
 
-  protected void init() {
+  protected override void init() {
     setCaption(CAPTION);
     glLineWidth(1);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE);
@@ -37,7 +37,7 @@
     screenResized();
   }
 
-  protected void close() {}
+  protected override void close() {}
 
   public static void drawLine(float x1, float y1, float z1,
                               float x2, float y2, float z2, float a = 1) {
--- a/src/abagames/mcd/shape.d
+++ b/src/abagames/mcd/shape.d
@@ -74,7 +74,7 @@
   float mass = 1;
   float shapeBoxScale = 1;
 
-  invariant {
+  invariant() {
     if (pos) {
       assert(pos.x <>= 0);
       assert(pos.y <>= 0);
@@ -158,7 +158,7 @@
     size = new Vector3(sx, sy, sz);
   }
 
-  public void recordLinePoints(LinePoint lp) {
+  public override void recordLinePoints(LinePoint lp) {
     lp.setPos(pos);
     lp.setSize(size);
     lp.record(-1, -1, 0);
@@ -171,7 +171,7 @@
     lp.record(-1, -1, 0);
   }
 
-  public void drawShadow(LinePoint lp) {
+  public override void drawShadow(LinePoint lp) {
     lp.setPos(pos);
     lp.setSize(size);
     if (!lp.setShadowColor())
@@ -224,7 +224,7 @@
     }
   }
 
-  public void recordLinePoints(LinePoint lp) {
+  public override void recordLinePoints(LinePoint lp) {
     lp.setPos(pos);
     lp.setSize(size);
     lp.record(-1, -1, 0);
@@ -237,7 +237,7 @@
     lp.record(-1, -1, 0);
   }
 
-  public void drawShadow(LinePoint lp) {
+  public override void drawShadow(LinePoint lp) {
     lp.setPos(pos);
     lp.setSize(size);
     if (!lp.setShadowColor())
@@ -262,7 +262,7 @@
     shapeBoxScale = 1;
   }
 
-  public void recordLinePoints(LinePoint lp) {
+  public override void recordLinePoints(LinePoint lp) {
     lp.setPos(pos);
     lp.setSize(size);
     lp.record( 0,  1, 0);
@@ -273,7 +273,7 @@
     lp.record( 0,  1, 0);
   }
 
-  public void drawShadow(LinePoint lp) {
+  public override void drawShadow(LinePoint lp) {
     lp.setPos(pos);
     lp.setSize(size);
     if (!lp.setShadowColor())
@@ -296,7 +296,7 @@
     size = new Vector3(sx, sy, sz);
   }
 
-  public void recordLinePoints(LinePoint lp) {
+  public override void recordLinePoints(LinePoint lp) {
     lp.setPos(pos);
     lp.setSize(size);
     lp.record(-1, -1, -1);
@@ -327,7 +327,7 @@
     lp.record(-1,  1, -1);
   }
 
-  public void drawShadow(LinePoint lp) {
+  public override void drawShadow(LinePoint lp) {
     lp.setPos(pos);
     lp.setSize(size);
     if (!lp.setShadowColor())
@@ -382,7 +382,7 @@
   float _alpha, _alphaTrg;
   bool _enableSpectrumColor;
 
-  invariant {
+  invariant() {
     if (pos) {
       assert(posIdx >= 0);
       assert(histIdx >= 0 && histIdx < HISTORY_MAX);
@@ -407,11 +407,11 @@
     pos = new Vector3[pointMax];
     posHist = new Vector3[][HISTORY_MAX];
     this.field = field;
-    foreach (inout Vector3 p; pos)
+    foreach (ref Vector3 p; pos)
         p = new Vector3;
-    foreach (inout Vector3[] pp; posHist) {
+    foreach (ref Vector3[] pp; posHist) {
       pp = new Vector3[pointMax];
-      foreach (inout Vector3 p; pp)
+      foreach (ref Vector3 p; pp)
         p = new Vector3;
     }
     spectrumColorRTrg = spectrumColorGTrg = spectrumColorBTrg = 0;
@@ -512,7 +512,7 @@
     glVertex3f(tx, ty, tz);
   }
 
-  private void calcTranslatedPos(inout float tx, inout float ty, inout float tz,
+  private void calcTranslatedPos(ref float tx, ref float ty, ref float tz,
                                  float ox, float oy, float oz) {
     float x = basePos.x + baseSize.x / 2 * ox;
     float y = basePos.y + baseSize.y / 2 * oy;
--- a/src/abagames/mcd/ship.d
+++ b/src/abagames/mcd/ship.d
@@ -78,7 +78,7 @@
   int titleCnt;
   bool _replayMode;
 
-  invariant {
+  invariant() {
     if (_pos && field) {
       assert(_pos.x > -field.size.x * 100);
       assert(_pos.x <  field.size.x * 100);
@@ -127,7 +127,7 @@
     linePoint = new LinePoint(field);
     linePoint.setSpectrumParams(0, 1.0f, 0, 1.0f);
     subShape = new CenterShape;
-    foreach (inout ShipTail t; tails)
+    foreach (ref ShipTail t; tails)
       t = new ShipTail(world, field, this, particles, connectedParticles);
     super.init();
   }
@@ -183,7 +183,7 @@
     remove();
   }
 
-  public void move() {
+  public override void move() {
     TwinStickPadState input;
     if (!_replayMode) {
       input = pad.getState();
@@ -347,7 +347,7 @@
     }
   }
 
-  public override void collide(OdeActor actor, inout bool hasCollision, inout bool checkFeedback) {
+  public override void collide(OdeActor actor, ref bool hasCollision, ref bool checkFeedback) {
     hasCollision = checkFeedback = false;
     if (cast(Wall) actor)
       hasCollision = true;
@@ -432,14 +432,14 @@
   public void recordLinePoints() {
     glPushMatrix();
     Screen.glTranslate(_pos);
-    glMultMatrixd(rot);
+    glMultMatrixd(rot.ptr);
     linePoint.beginRecord();
     shape.recordLinePoints(linePoint);
     linePoint.endRecord();
     glPopMatrix();
   }
 
-  public void draw() {
+  public override void draw() {
     shots.draw();
     enhancedShots.draw();
     if (restartCnt > 0)
@@ -453,7 +453,7 @@
     linePoint.draw();
     glPushMatrix();
     Screen.glTranslate(_pos);
-    glMultMatrixd(rot);
+    glMultMatrixd(rot.ptr);
     subShape.draw();
     glPopMatrix();
   }
@@ -525,7 +525,7 @@
   LinePoint linePoint;
   dJointID joint;
 
-  invariant {
+  invariant() {
     if (_pos) {
       assert(_pos.x <>= 0);
       assert(_pos.y <>= 0);
@@ -593,7 +593,7 @@
     linePoint.init();
   }
 
-  public void move() {
+  public override void move() {
     dReal *p = dBodyGetPosition(_bodyId);
     _pos.x = p[0];
     _pos.y = p[1];
@@ -622,7 +622,7 @@
     super.remove();
   }
 
-  public override void collide(OdeActor actor, inout bool hasCollision, inout bool checkFeedback) {
+  public override void collide(OdeActor actor, ref bool hasCollision, ref bool checkFeedback) {
     hasCollision = checkFeedback = false;
     if (cast(Wall) actor || cast(ShipTail) actor || cast(Ship) actor)
       hasCollision = true;
@@ -643,7 +643,7 @@
   public void recordLinePoints() {
     glPushMatrix();
     Screen.glTranslate(_pos);
-    glMultMatrixd(rot);
+    glMultMatrixd(rot.ptr);
     glScalef(size.x, size.y, size.z);
     linePoint.beginRecord();
     shape.recordLinePoints(linePoint);
@@ -651,7 +651,7 @@
     glPopMatrix();
   }
 
-  public void draw() {
+  public override void draw() {
     linePoint.drawSpectrum();
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     shape.drawShadow(linePoint);
--- a/src/abagames/mcd/shot.d
+++ b/src/abagames/mcd/shot.d
@@ -37,7 +37,7 @@
   ShapeGroup shape;
   LinePoint linePoint;
 
-  invariant {
+  invariant() {
     if (pos) {
       assert(pos.x <>= 0);
       assert(pos.y <>= 0);
@@ -82,7 +82,7 @@
     doCollide();
   }
 
-  public override void collide(OdeActor actor, inout bool hasCollision, inout bool checkFeedback) {
+  public override void collide(OdeActor actor, ref bool hasCollision, ref bool checkFeedback) {
     hasCollision = checkFeedback = false;
     Enemy e = cast(Enemy) actor;
     if (e) {
--- a/src/abagames/mcd/soundmanager.d
+++ b/src/abagames/mcd/soundmanager.d
@@ -16,17 +16,17 @@
  */
 public class SoundManager: abagames.util.sdl.sound.SoundManager {
  private static:
-  char[][] seFileName =
+  string[] seFileName =
     ["shot.wav", "hit.wav", "bullethit.wav", "destroyed.wav", "addtail.wav",
      "breaktail.wav", "enhancedshot.wav", "shipdestroyed.wav", "extend.wav"];
   int[] seChannel =
     [0, 1, 2, 3, 4, 5, 0, 6, 7];
-  Music[char[]] bgm;
-  Chunk[char[]] se;
-  bool[char[]] seMark;
+  Music[string] bgm;
+  Chunk[string] se;
+  bool[string] seMark;
   Rand rand;
-  char[][] bgmFileName;
-  char[] currentBgm;
+  string[] bgmFileName;
+  string currentBgm;
   int prevBgmIdx;
   int nextIdxMv;
   bool bgmDisabled = false;
@@ -43,11 +43,12 @@
   }
 
   private static void loadMusics() {
-    Music[char[]] musics;
-    char[][] files = listdir(Music.dir);
-    foreach (char[] fileName; files) {
-      char[] ext = getExt(fileName);
-      if (ext != "ogg" && ext != "wav")
+    Music[string] musics;
+    auto files = dirEntries(Music.dir, SpanMode.shallow);
+    foreach (string fullFileName; files) {
+      string fileName = baseName(fullFileName);
+      string ext = extension(fileName);
+      if (ext != ".ogg" && ext != ".wav")
         continue;
       Music music = new Music();
       music.load(fileName);
@@ -59,7 +60,7 @@
 
   private static void loadChunks() {
     int i = 0;
-    foreach (char[] fileName; seFileName) {
+    foreach (string fileName; seFileName) {
       Chunk chunk = new Chunk();
       chunk.load(fileName, seChannel[i]);
       se[fileName] = chunk;
@@ -69,7 +70,7 @@
     }
   }
 
-  public static void playBgm(char[] name) {
+  public static void playBgm(string name) {
     currentBgm = name;
     if (bgmDisabled)
       return;
@@ -78,7 +79,7 @@
   }
 
   public static void playBgm() {
-    int bgmIdx = rand.nextInt(bgm.length);
+    int bgmIdx = rand.nextInt(cast(int)bgm.length);
     nextIdxMv = rand.nextInt(2) * 2 - 1;
     prevBgmIdx = bgmIdx;
     playBgm(bgmFileName[bgmIdx]);
@@ -87,7 +88,7 @@
   public static void nextBgm() {
     int bgmIdx = prevBgmIdx + nextIdxMv;
     if (bgmIdx < 0)
-      bgmIdx = bgm.length - 1;
+      bgmIdx = cast(int)bgm.length - 1;
     else if (bgmIdx >= bgm.length)
       bgmIdx = 0;
     prevBgmIdx = bgmIdx;
@@ -106,15 +107,15 @@
     Music.haltMusic();
   }
 
-  public static void playSe(char[] name) {
+  public static void playSe(string name) {
     if (seDisabled)
       return;
     seMark[name] = true;
   }
 
   public static void playMarkedSes() {
-    char[][] keys = seMark.keys;
-    foreach (char[] key; keys) {
+    string[] keys = seMark.keys;
+    foreach (string key; keys) {
       if (seMark[key]) {
         se[key].play();
         seMark[key] = false;
@@ -123,8 +124,8 @@
   }
 
   public static void clearMarkedSes() {
-    char[][] keys = seMark.keys;
-    foreach (char[] key; keys)
+    string[] keys = seMark.keys;
+    foreach (string key; keys)
       seMark[key] = false;
   }
 
--- a/src/abagames/mcd/spec.d
+++ b/src/abagames/mcd/spec.d
@@ -53,7 +53,7 @@
       if (state.topBullet)
         state.topBullet.activated = true;
       state.linePoint.enableSpectrumColor = true;
-      switch (state.type) {
+      switch (state.type) { default: break;
       case CentType.TO_AND_FROM:
         enemy.slowLinearVel(CentHead.SLOW_VELOCITY_RATIO * state.slowVelocityRatio *
                             (1 + (state.turnCnt * 0.1f)));
@@ -79,7 +79,7 @@
       state.turnCnt--;
     float ad;
     float angularForce = ANGULAR_FORCE_BASE;
-    switch (state.type) {
+    switch (state.type) { default: break;
     case CentType.TO_AND_FROM:
       int ti = -1;
       if (state.pos.x > field.size.x * 0.5f)
@@ -210,7 +210,7 @@
     if (state.isHead) {
       glPushMatrix();
       Screen.glTranslate(state.pos);
-      glMultMatrixd(state.rot);
+      glMultMatrixd(state.rot.ptr);
       glScalef(state.sizeScale.x, state.sizeScale.y, state.sizeScale.z);
       subShape.draw();
       glPopMatrix();
@@ -229,20 +229,20 @@
   BasicBarrageType type;
   float speedRank;
   int interval;
-  char[] wayMorphBml;
+  string wayMorphBml;
   float wayMorphRank;
-  char[] barMorphBml;
+  string barMorphBml;
   float barMorphRank;
  private:
 
-  invariant {
+  invariant() {
     assert(speedRank > 0 && speedRank < 10);
     assert(interval > 0);
   }
 
   public void set(BulletPool bullets, Ship ship, EnemyState state, float orderRatio = 0) {
     state.barrage.clear();
-    switch (type) {
+    switch (type) { default: break;
     case BasicBarrageType.AIM:
     case BasicBarrageType.FRONT:
     case BasicBarrageType.PLUMB:
@@ -268,7 +268,7 @@
     if (!state.topBullet)
       return;
     state.topBullet.activated = false;
-    switch (type) {
+    switch (type) { default: break;
     case BasicBarrageType.AIM:
     case BasicBarrageType.AIM_IN_ORDER:
       break;
@@ -289,7 +289,7 @@
 public template CentHeadInitImpl() {
   protected void initLengthAndSize(int size) {
     float ss;
-    switch (size) {
+    switch (size) { default: break;
     case 0:
       bodyLength = 4 + rand.nextInt(4);
       ss = 0.9f + rand.nextFloat(0.3f);
@@ -316,7 +316,7 @@
   }
 
   protected void calcBarrageSpeedAndInterval(
-    inout float rank, float br, out float speed, out int interval,
+    ref float rank, float br, out float speed, out int interval,
     float minInterval = 20, float maxInterval = 120) {
     float sr = br * (0.5f + rand.nextSignedFloat(0.2f));
     float ir = br - sr;
@@ -335,7 +335,7 @@
   }
 
   protected void calcForwardForceAndSlowVelocity(
-    inout float rank, int size,
+    ref float rank, int size,
     out float forwardForceScale, out float slowVelocityRatio) {
     forwardForceScale = 1;
     if (rand.nextInt(5) == 0) {
@@ -367,7 +367,7 @@
   static const float COLOR_G = 0.25f;
   static const float COLOR_B = 1.0f;
  private:
-  static const char[][] BAR_MORPH_BML = [
+  static const string[] BAR_MORPH_BML = [
     "baraccel.xml", "whip.xml", "slidebar.xml", "slidebaraccel.xml", "slidewhip.xml"];
 
   public this(Field field, Ship ship, BulletPool bullets, World world, float rank, int size) {
@@ -388,7 +388,7 @@
       float br = rk * (0.1f * size + rand.nextFloat(0.1f));
       float brv = calcBarrageRank(br);
       if (brv >= 0.1f) {
-        bodyBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(BAR_MORPH_BML.length)];
+        bodyBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(cast(int)BAR_MORPH_BML.length)];
         bodyBarrage.barMorphRank = brv;
         rk -= br * 2;
       } else {
@@ -406,7 +406,7 @@
     float br = rk * (0.1f * size + rand.nextFloat(0.3f));
     float brv = calcBarrageRank(br);
     if (brv >= 0.1f) {
-      headBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(BAR_MORPH_BML.length)];
+      headBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(cast(int)BAR_MORPH_BML.length)];
       headBarrage.barMorphRank = brv;
       rk -= br * 2;
     } else {
@@ -418,7 +418,7 @@
     slowVelocityRatio = svr;
     float sp;
     int iv;
-    switch (size) {
+    switch (size) { default: break;
     case 0:
       calcBarrageSpeedAndInterval(rk, rk, sp, iv);
       break;
@@ -450,9 +450,9 @@
   static const float COLOR_G = 0.25f;
   static const float COLOR_B = 0.75f;
  private:
-  static const char[][] WAY_MORPH_BML = [
+  static const string[] WAY_MORPH_BML = [
     "accnway.xml", "decnway.xml", "nway.xml"];
-  static const char[][] BAR_MORPH_BML = [
+  static const string[] BAR_MORPH_BML = [
     "bar.xml", "baraccel.xml", "whip.xml"];
 
   public this(Field field, Ship ship, BulletPool bullets, World world, float rank, int size) {
@@ -470,7 +470,7 @@
       float br = rk * (0.1f + rand.nextFloat(0.1f));
       float brv = calcBarrageRank(br);
       if (brv >= 0.1f) {
-        bodyBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(BAR_MORPH_BML.length)];
+        bodyBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(cast(int)BAR_MORPH_BML.length)];
         bodyBarrage.barMorphRank = brv;
         rk -= br * 2;
       } else {
@@ -485,7 +485,7 @@
     headBarrage = new CentBarrage;
     headBarrage.type = CentBarrage.BasicBarrageType.FRONT;
     float wr;
-    switch (size) {
+    switch (size) { default: break;
     case 0:
       wr = 0;
       break;
@@ -500,14 +500,14 @@
     float wrv = calcBarrageRank(wr);
     float brv = calcBarrageRank(br);
     if (wrv >= 0.2f) {
-      headBarrage.wayMorphBml = WAY_MORPH_BML[rand.nextInt(WAY_MORPH_BML.length)];
+      headBarrage.wayMorphBml = WAY_MORPH_BML[rand.nextInt(cast(int)WAY_MORPH_BML.length)];
       headBarrage.wayMorphRank = wrv;
       rk -= wr * 2;
     } else {
       headBarrage.wayMorphBml = null;
     }
     if (brv >= 0.1f) {
-      headBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(BAR_MORPH_BML.length)];
+      headBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(cast(int)BAR_MORPH_BML.length)];
       headBarrage.barMorphRank = brv;
       rk -= br * 2;
     } else {
@@ -544,9 +544,9 @@
   static const float COLOR_G = 0.75f;
   static const float COLOR_B = 0.75f;
  private:
-  static const char[][] WAY_MORPH_BML = [
+  static const string[] WAY_MORPH_BML = [
     "nway.xml", "round.xml"];
-  static const char[][] BAR_MORPH_BML = [
+  static const string[] BAR_MORPH_BML = [
     "bar.xml", "baraccel.xml", "whip.xml",
     "slidebar.xml", "slidebaraccel.xml", "slidewhip.xml"];
 
@@ -563,7 +563,7 @@
     float br = rk * (0.1f * size + rand.nextFloat(0.1f));
     float brv = calcBarrageRank(br);
     if (brv >= 0.1f) {
-      bodyBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(BAR_MORPH_BML.length)];
+      bodyBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(cast(int)BAR_MORPH_BML.length)];
       bodyBarrage.barMorphRank = brv;
       rk -= br * 2;
     } else {
@@ -571,7 +571,7 @@
     }
     float sp;
     int iv;
-    switch (size) {
+    switch (size) { default: break;
     case 0:
       calcBarrageSpeedAndInterval(rk, rk * 0.5f, sp, iv, 10, 60);
       break;
@@ -594,20 +594,20 @@
       headBarrage = new CentBarrage;
       headBarrage.type = CentBarrage.BasicBarrageType.FRONT;
       float wr = rk * (size * 0.2f + rand.nextFloat(0.2f));
-      float br = rk * rand.nextFloat(0.2f);
+      float br_ = rk * rand.nextFloat(0.2f);
       float wrv = calcBarrageRank(wr);
-      float brv = calcBarrageRank(br);
+      float brv_ = calcBarrageRank(br_);
       if (wrv >= 0.2f) {
-        headBarrage.wayMorphBml = WAY_MORPH_BML[rand.nextInt(WAY_MORPH_BML.length)];
+        headBarrage.wayMorphBml = WAY_MORPH_BML[rand.nextInt(cast(int)WAY_MORPH_BML.length)];
         headBarrage.wayMorphRank = wrv;
         rk -= wr * 2;
       } else {
         headBarrage.wayMorphBml = null;
       }
-      if (brv >= 0.1f) {
-        headBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(BAR_MORPH_BML.length)];
-        headBarrage.barMorphRank = brv;
-        rk -= br * 2;
+      if (brv_ >= 0.1f) {
+        headBarrage.barMorphBml = BAR_MORPH_BML[rand.nextInt(cast(int)BAR_MORPH_BML.length)];
+        headBarrage.barMorphRank = brv_;
+        rk -= br_ * 2;
       } else {
         headBarrage.barMorphBml = null;
       }
@@ -615,11 +615,11 @@
       calcForwardForceAndSlowVelocity(rk, size, ffs, svr);
       forwardForceScale = ffs;
       slowVelocityRatio = svr;
-      float sp;
-      int iv;
-      calcBarrageSpeedAndInterval(rk, rk, sp, iv, 10, 60);
-      headBarrage.speedRank = sp;
-      headBarrage.interval = iv;
+      float sp_;
+      int iv_;
+      calcBarrageSpeedAndInterval(rk, rk, sp_, iv_, 10, 60);
+      headBarrage.speedRank = sp_;
+      headBarrage.interval = iv_;
     }
     _colorR = COLOR_R;
     _colorG = COLOR_G;
@@ -644,7 +644,7 @@
   CentBarrage headBarrage, bodyBarrage;
  private:
 
-  invariant {
+  invariant() {
     if (sizeScale) {
       assert(sizeScale.x > 0);
       assert(sizeScale.y > 0);
--- a/src/abagames/mcd/stagemanager.d
+++ b/src/abagames/mcd/stagemanager.d
@@ -48,7 +48,7 @@
     this.bullets = bullets;
     this.enemies = enemies;
     rand = new Rand;
-    foreach (inout Appearance a; appearances)
+    foreach (ref Appearance a; appearances)
       a = new Appearance(field, ship, bullets, world, this);
     _blockSpec = new Block(field, ship, bullets, world);
   }
@@ -68,7 +68,7 @@
     TailParticle.setRandSeed(randSeed);
     Field.setRandSeed(randSeed);
     SoundManager.setRandSeed(randSeed);
-    dRandSetSeed(randSeed);
+    dRandSetSeed(cast(int)randSeed);
     clearAppearances();
     cnt = 0;
     rankDownCnt = 0;
@@ -99,7 +99,7 @@
       if (atypeMax > 16)
         atypeMax = 16;
       int atype = rand.nextInt(atypeMax);
-      switch (atype) {
+      switch (atype) { default: break;
       case 0:
         addAppearance(rank, Appearance.EnemyType.CHASE, 0, 3, 500);
         addAppearance(0, Appearance.EnemyType.BLOCK, 0, 6, 250);
@@ -285,7 +285,7 @@
 
   public void set(float rank, int type, int size, int num, int interval) {
     appType = AppearanceType.NORMAL;
-    switch (type) {
+    switch (type) { default: break;
     case EnemyType.TO_AND_FROM:
       spec = new CentHeadToAndFrom(field, ship, bullets, world, rank, size);
       break;
@@ -317,7 +317,7 @@
     cnt -= cntInc;
     if (cnt < 0) {
       cnt = interval;
-      switch (appType) {
+      switch (appType) { default: break;
       case AppearanceType.NORMAL:
         stageManager.set(spec,
                          rand.nextSignedFloat(field.size.x * 0.5f),
@@ -329,7 +329,7 @@
         float ys = 1 + rand.nextFloat(1);
         float zs = 1 + rand.nextFloat(1);
         if (rand.nextInt(3) == 0) {
-          switch (rand.nextInt(3)) {
+          switch (rand.nextInt(3)) { default: break;
           case 0:
             xs *= (2 + rand.nextFloat(2));
             break;
--- a/src/abagames/mcd/title.d
+++ b/src/abagames/mcd/title.d
@@ -6,6 +6,7 @@
 module abagames.mcd.title;
 
 private import std.string;
+private import std.conv;
 private import opengl;
 private import abagames.mcd.screen;
 private import abagames.mcd.field;
@@ -70,7 +71,7 @@
       rn = PrefData.RANKING_NUM;
     float y = 120;
     for (int i = 0; i < rn; i++) {
-      char[] rstr;
+      string rstr;
       switch (i) {
       case 0:
         rstr = "1ST";
@@ -82,7 +83,7 @@
         rstr = "3RD";
         break;
       default:
-        rstr = std.string.toString(i + 1) ~ "TH";
+        rstr = to!string(i + 1) ~ "TH";
         break;
       }
       if (i < 9)
--- a/src/abagames/util/actor.d
+++ b/src/abagames/util/actor.d
@@ -33,7 +33,7 @@
  public:
   T[] actor;
  protected:
-  int actorIdx = 0;
+  ptrdiff_t actorIdx = 0;
  private:
 
   public this() {}
@@ -44,7 +44,7 @@
 
   protected void createActors(int n, Object[] args = null) {
     actor = new T[n];
-    foreach (inout T a; actor) {
+    foreach (ref T a; actor) {
       a = new T;
       a.exists = false;
       a.init(args);
--- a/src/abagames/util/iterator.d
+++ b/src/abagames/util/iterator.d
@@ -35,10 +35,10 @@
   }
 }
 
-alias ArrayIterator!(char[]) StringIterator;
+alias ArrayIterator!(string) StringIterator;
 
 public class NoMoreItemsException: Exception {
-  public this(char[] msg) {
+  public this(string msg) {
     super(msg);
   }
 }
--- a/src/abagames/util/logger.d
+++ b/src/abagames/util/logger.d
@@ -7,6 +7,7 @@
 
 private import std.cstream;
 private import std.string;
+private import std.conv;
 
 /**
  * Logger(error/info).
@@ -18,7 +19,7 @@
 
 public class Logger {
 
-  public static void info(char[] msg, bool nline = true) {
+  public static void info(string msg, bool nline = true) {
     // Win32 exe crashes if it writes something to stderr.
     /*if (nline)
       std.cstream.derr.writeLine(msg);
@@ -28,24 +29,20 @@
 
   public static void info(double n, bool nline = true) {
     /*if (nline)
-      std.cstream.derr.writeLine(std.string.toString(n));
+      std.cstream.derr.writeLine(to!string(n));
     else
-      std.cstream.derr.writeString(std.string.toString(n) ~ " ");*/
+      std.cstream.derr.writeString(to!string(n) ~ " ");*/
   }
 
-  private static void putMessage(char[] msg) {
+  private static void putMessage(string msg) {
     MessageBoxA(null, std.string.toStringz(msg), "Error", MB_OK | MB_ICONEXCLAMATION);
   }
 
-  public static void error(char[] msg) {
+  public static void error(string msg) {
     putMessage("Error: " ~ msg);
   }
 
-  public static void error(Exception e) {
-    putMessage("Error: " ~ e.toString());
-  }
-
-  public static void error(Error e) {
+  public static void error(Throwable e) {
     putMessage("Error: " ~ e.toString());
   }
 }
@@ -54,7 +51,7 @@
 
 public class Logger {
 
-  public static void info(char[] msg, bool nline = true) {
+  public static void info(string msg, bool nline = true) {
     if (nline)
       std.cstream.derr.writeLine(msg);
     else
@@ -63,20 +60,16 @@
 
   public static void info(double n, bool nline = true) {
     if (nline)
-      std.cstream.derr.writeLine(std.string.toString(n));
+      std.cstream.derr.writeLine(to!string(n));
     else
-      std.cstream.derr.writeString(std.string.toString(n) ~ " ");
+      std.cstream.derr.writeString(to!string(n) ~ " ");
   }
 
-  public static void error(char[] msg) {
+  public static void error(string msg) {
     std.cstream.derr.writeLine("Error: " ~ msg);
   }
 
-  public static void error(Exception e) {
-    std.cstream.derr.writeLine("Error: " ~ e.toString());
-  }
-
-  public static void error(Error e) {
+  public static void error(Throwable e) {
     std.cstream.derr.writeLine("Error: " ~ e.toString());
     if (e.next)
       error(e.next);
--- a/src/abagames/util/math.d
+++ b/src/abagames/util/math.d
@@ -14,13 +14,13 @@
 public class Math {
  private:
 
-  public static void normalizeDeg(inout float d) {
+  public static void normalizeDeg(ref float d) {
     if (d < -PI)
       d = PI * 2 - (-d % (PI * 2));
     d = (d + PI) % (PI * 2) - PI;
   }
 
-  public static void normalizeDeg360(inout float d) {
+  public static void normalizeDeg360(ref float d) {
     if (d < -180)
       d = 360 - (-d % 360);
     d = (d + 180) % 360 - 180;
--- a/src/abagames/util/ode/odeactor.d
+++ b/src/abagames/util/ode/odeactor.d
@@ -54,7 +54,7 @@
     transformedGeomId = new dGeomID[GEOM_NUM];
     if (checkFeedback) {
       contactJoint = new ContactJoint[CONTACT_JOINT_NUM];
-      foreach (inout ContactJoint cj; contactJoint) {
+      foreach (ref ContactJoint cj; contactJoint) {
         cj.pos = new Vector3;
         cj.feedbackForce = new Vector3;
       }
@@ -309,7 +309,7 @@
     dBodySetRotation(_bodyId, matrix);
   }
 
-  public void collide(OdeActor actor, inout bool hasCollision, inout bool checkFeedback) {
+  public void collide(OdeActor actor, ref bool hasCollision, ref bool checkFeedback) {
     hasCollision = checkFeedback = false;
   }
 
--- a/src/abagames/util/rand.d
+++ b/src/abagames/util/rand.d
@@ -6,7 +6,7 @@
 module abagames.util.rand;
 
 private import std.stream;
-private import std.date;
+private import std.datetime;
 
 /**
  * Random number generator.
@@ -14,12 +14,12 @@
 public class Rand {
   
   public this() {
-    d_time timer = getUTCtime();
-    init_genrand(timer);
+    long timer = Clock.currStdTime();
+    init_genrand(cast(uint)timer);
   }
 
   public void setSeed(long n) {
-    init_genrand(n);
+    init_genrand(cast(uint)n);
   }
 
   public uint nextInt32() {
@@ -55,7 +55,7 @@
      Matthe Bellew, and Isaku Wada
    Andrew C. Edwards  v0.1  30 September 2003  edwardsac@ieee.org
 
-   Before using, initialize the state by using init_genrand(seed) 
+   Before using, initialize the state by using init_genrand(cast(uint)seed) 
    or init_by_array(init_key, key_length).
 
    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
@@ -122,7 +122,7 @@
 {
     state[0]= s & 0xffffffffUL;
     for (int j=1; j<N; j++) {
-        state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j); 
+        state[j] = (1812433253U * (state[j-1] ^ (state[j-1] >> 30)) + j); 
         /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
         /* In the previous versions, MSBs of the seed affect   */
         /* only MSBs of the array state[].                        */
@@ -140,11 +140,11 @@
 void init_by_array(uint init_key[], uint key_length)
 {
     int i, j, k;
-    init_genrand(19650218UL);
+    init_genrand(cast(uint)19650218UL);
     i=1; j=0;
     k = (N>key_length ? N : key_length);
     for (; k; k--) {
-        state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525UL))
+        state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1664525U))
           + init_key[j] + j; /* non linear */
         state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
         i++; j++;
@@ -152,7 +152,7 @@
         if (j>=key_length) j=0;
     }
     for (k=N-1; k; k--) {
-        state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL))
+        state[i] = (state[i] ^ ((state[i-1] ^ (state[i-1] >> 30)) * 1566083941U))
           - i; /* non linear */
         state[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
         i++;
@@ -165,14 +165,14 @@
 
 void next_state()
 {
-    uint *p=state;
+    uint *p=state.ptr;
 
-    /* if init_genrand() has not been called, */
+    /* if init_genrand(cast(uint)) has not been called, */
     /* a default initial seed is used         */
-    if (initf==0) init_genrand(5489UL);
+    if (initf==0) init_genrand(cast(uint)5489UL);
 
     left = N;
-    next = state;
+    next = state.ptr;
     
     for (int j=N-M+1; --j; p++) 
         *p = p[M] ^ TWIST(p[0], p[1]);
--- a/src/abagames/util/sdl/recordableinput.d
+++ b/src/abagames/util/sdl/recordableinput.d
@@ -39,7 +39,7 @@
 }
 
 public class NoRecordDataException: Exception {
-  public this(char[] msg) {
+  public this(string msg) {
     super(msg);
   }
 }
--- a/src/abagames/util/sdl/screen3d.d
+++ b/src/abagames/util/sdl/screen3d.d
@@ -6,6 +6,7 @@
 module abagames.util.sdl.screen3d;
 
 private import std.string;
+private import std.conv;
 private import SDL;
 private import opengl;
 private import abagames.util.vector;
@@ -32,7 +33,7 @@
     // Initialize SDL.
     if (SDL_Init(SDL_INIT_VIDEO) < 0) {
       throw new SDLInitFailedException(
-        "Unable to initialize SDL: " ~ std.string.toString(SDL_GetError()));
+        "Unable to initialize SDL: " ~ to!string(SDL_GetError()));
     }
     // Create an OpenGL screen.
     if (_windowMode) {
@@ -42,7 +43,7 @@
     } 
     if (SDL_SetVideoMode(_width, _height, 0, _videoFlags) == null) {
       throw new SDLInitFailedException
-        ("Unable to create SDL screen: " ~ std.string.toString(SDL_GetError()));
+        ("Unable to create SDL screen: " ~ to!string(SDL_GetError()));
     }
     glViewport(0, 0, width, height);
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -57,7 +58,7 @@
     int screen_height = _height;
     if (SDL_SetVideoMode(screen_width, screen_height, 0, _videoFlags) == null) {
       throw new SDLInitFailedException
-        ("Unable to resize SDL screen: " ~ std.string.toString(SDL_GetError()));
+        ("Unable to resize SDL screen: " ~ to!string(SDL_GetError()));
     }
 
     // adjust width and height to maintain correct aspect ratio
@@ -107,10 +108,10 @@
     if (error == GL_NO_ERROR)
       return;
     closeSDL();
-    throw new Exception("OpenGL error(" ~ std.string.toString(error) ~ ")");
+    throw new Exception("OpenGL error(" ~ to!string(error) ~ ")");
   }
 
-  protected void setCaption(char[] name) {
+  protected void setCaption(string name) {
     SDL_WM_SetCaption(std.string.toStringz(name), null);
   }
 
--- a/src/abagames/util/sdl/sdlexception.d
+++ b/src/abagames/util/sdl/sdlexception.d
@@ -9,7 +9,7 @@
  * SDL initialize failed.
  */
 public class SDLInitFailedException: Exception {
-  public this(char[] msg) {
+  public this(string msg) {
     super(msg);
   }
 }
@@ -18,7 +18,7 @@
  * SDL general exception.
  */
 public class SDLException: Exception {
-  public this(char[] msg) {
+  public this(string msg) {
     super(msg);
   }
 }
--- a/src/abagames/util/sdl/sound.d
+++ b/src/abagames/util/sdl/sound.d
@@ -6,6 +6,7 @@
 module abagames.util.sdl.sound;
 
 private import std.string;
+private import std.conv;
 private import SDL;
 private import SDL_mixer;
 private import abagames.util.sdl.sdlexception;
@@ -28,7 +29,7 @@
     if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
       noSound = true;
       throw new SDLInitFailedException
-        ("Unable to initialize SDL_AUDIO: " ~ std.string.toString(SDL_GetError()));
+        ("Unable to initialize SDL_AUDIO: " ~ to!string(SDL_GetError()));
     }
     audio_rate = 44100;
     audio_format = AUDIO_S16;
@@ -37,7 +38,7 @@
     if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0) {
       noSound = true;
       throw new SDLInitFailedException
-        ("Couldn't open audio: " ~ std.string.toString(SDL_GetError()));
+        ("Couldn't open audio: " ~ to!string(SDL_GetError()));
     }
     Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
   }
@@ -56,8 +57,8 @@
  * Music / Chunk.
  */
 public interface Sound {
-  public void load(char[] name);
-  public void load(char[] name, int ch);
+  public void load(string name);
+  public void load(string name, int ch);
   public void free();
   public void play();
   public void fade();
@@ -67,23 +68,23 @@
 public class Music: Sound {
  public:
   static int fadeOutSpeed = 1280;
-  static char[] dir = "/usr/share/games/mu-cade/sounds/musics";
+  static string dir = "/usr/share/games/mu-cade/sounds/musics";
  private:
   Mix_Music* music;
 
-  public void load(char[] name) {
+  public void load(string name) {
     if (SoundManager.noSound)
       return;
-    char[] fileName = dir ~ "/" ~ name;
+    string fileName = dir ~ "/" ~ name;
     music = Mix_LoadMUS(std.string.toStringz(fileName));
     if (!music) {
       SoundManager.noSound = true;
       throw new SDLException("Couldn't load: " ~ fileName ~ 
-                             " (" ~ std.string.toString(Mix_GetError()) ~ ")");
+                             " (" ~ to!string(Mix_GetError()) ~ ")");
     }
   }
   
-  public void load(char[] name, int ch) {
+  public void load(string name, int ch) {
     load(name);
   }
 
@@ -131,24 +132,24 @@
 
 public class Chunk: Sound {
  public:
-  static char[] dir = "/usr/share/games/mu-cade/sounds/chunks";
+  static string dir = "/usr/share/games/mu-cade/sounds/chunks";
  private:
   Mix_Chunk* chunk;
   int chunkChannel;
 
-  public void load(char[] name) {
+  public void load(string name) {
     load(name, 0);
   }
   
-  public void load(char[] name, int ch) {
+  public void load(string name, int ch) {
     if (SoundManager.noSound)
       return;
-    char[] fileName = dir ~ "/" ~ name;
+    string fileName = dir ~ "/" ~ name;
     chunk = Mix_LoadWAV(std.string.toStringz(fileName));
     if (!chunk) {
       SoundManager.noSound = true;
       throw new SDLException("Couldn't load: " ~ fileName ~ 
-                             " (" ~ std.string.toString(Mix_GetError()) ~ ")");
+                             " (" ~ to!string(Mix_GetError()) ~ ")");
     }
     chunkChannel = ch;
   }
--- a/src/abagames/util/sdl/texture.d
+++ b/src/abagames/util/sdl/texture.d
@@ -16,19 +16,19 @@
  */
 public class Texture {
  public:
-  static char[] imagesDir = "/usr/share/games/mu-cade/images/";
-  static SDL_Surface*[char[]] surface;
+  static string imagesDir = "/usr/share/games/mu-cade/images/";
+  static SDL_Surface*[string] surface;
  private:
   GLuint num, maskNum;
   int textureNum, maskTextureNum;
   Uint32[128 * 128] pixels;
   Uint32[128 * 128] maskPixels;
 
-  public static SDL_Surface* loadBmp(char[] name) {
+  public static SDL_Surface* loadBmp(string name) {
     if (name in surface) {
       return surface[name];
     } else {
-      char[] fileName = imagesDir ~ name;
+      string fileName = imagesDir ~ name;
       SDL_Surface *s = SDL_LoadBMP(std.string.toStringz(fileName));
       if (!s)
         throw new SDLInitFailedException("Unable to load: " ~ fileName);
@@ -55,7 +55,7 @@
     }
   }
 
-  public this(char[] name) {
+  public this(string name) {
     SDL_Surface *s = loadBmp(name);
     glGenTextures(1, &num);
     glBindTexture(GL_TEXTURE_2D, num);
@@ -65,7 +65,7 @@
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   }
 
-  public this(char[] name, int sx, int sy, int xn, int yn, int panelWidth, int panelHeight,
+  public this(string name, int sx, int sy, int xn, int yn, int panelWidth, int panelHeight,
               Uint32 maskColor = 0xffffffffu) {
     SDL_Surface *s = loadBmp(name);
     Uint32* surfacePixels = cast(Uint32*) s.pixels;
--- a/src/abagames/util/sdl/twinstickpad.d
+++ b/src/abagames/util/sdl/twinstickpad.d
@@ -65,7 +65,7 @@
         state.right.x = state.right.y = 0;
       } else {
         ry = -ry;
-        float rd = atan2(rx, ry) * reverse + rotate;
+        float rd = atan2(cast(float)rx, cast(float)ry) * reverse + rotate;
         assert(rd <>= 0);
         float rl = sqrt(cast(float) rx * rx + cast(float) ry * ry);
         assert(rl <>= 0);
@@ -162,7 +162,7 @@
   int button;
  private:
 
-  invariant {
+  invariant() {
     assert(left.x >= -1 && left.x <= 1);
     assert(left.y >= -1 && left.y <= 1);
     assert(right.x >= -1 && right.x <= 1);
@@ -227,7 +227,11 @@
   mixin RecordableInput!(TwinStickPadState);
  private:
 
-  public TwinStickPadState getState(bool doRecord = true) {
+  public override TwinStickPadState getState() {
+    return getState(true);
+  }
+
+  public TwinStickPadState getState(bool doRecord) {
     TwinStickPadState s = super.getState();
     if (doRecord)
       record(s);
--- a/src/abagames/util/tokenizer.d
+++ b/src/abagames/util/tokenizer.d
@@ -7,6 +7,7 @@
 
 private import std.stream;
 private import std.string;
+private import std.conv;
 
 /**
  * Tokenizer.
@@ -14,17 +15,17 @@
 public class Tokenizer {
  private:
 
-  public static char[][] readFile(char[] fileName, char[] separator) {
-    char[][] result;
-    auto File fd = new File;
+  public static string[] readFile(string fileName, string separator) {
+    string[] result;
+    scope File fd = new File;
     fd.open(fileName);
     for (;;) {
-      char[] line = fd.readLine();
+      string line = to!string(fd.readLine());
       if (!line)
         break;
-      char[][] spl = std.string.split(line, separator);
-      foreach (char[] s; spl) {
-        char[] r = strip(s);
+      string[] spl = std.string.split(line, separator);
+      foreach (string s; spl) {
+        string r = strip(s);
         if (r.length > 0)
           result ~= r;
       }
@@ -40,7 +41,7 @@
 public class CSVTokenizer {
  private:
 
-  public static char[][] readFile(char[] fileName) {
+  public static string[] readFile(string fileName) {
     return Tokenizer.readFile(fileName, ",");
   }
 }
--- a/src/abagames/util/vector.d
+++ b/src/abagames/util/vector.d
@@ -7,6 +7,7 @@
 
 private import std.math;
 private import std.string;
+private import std.conv;
 
 /**
  * Vector.
@@ -219,8 +220,8 @@
     x = tx;
   }
 
-  public char[] toString() {
-    return "(" ~ std.string.toString(x) ~ ", " ~ std.string.toString(y) ~ ")";
+  public override string toString() {
+    return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ")";
   }
 }
 
@@ -336,7 +337,7 @@
     z /= a;
   }
 
-  public char[] toString() {
-    return "(" ~ std.string.toString(x) ~ ", " ~ std.string.toString(y) ~ ", " ~ std.string.toString(z) ~ ")";
+  public override string toString() {
+    return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ", " ~ to!string(z) ~ ")";
   }
 }
--- a/src/abagames/util/sdl/mainloop.d
+++ b/src/abagames/util/sdl/mainloop.d
@@ -93,7 +93,7 @@
       frame = cast(int) (nowTick - prvTickCount) / itv;
       if (frame <= 0) {
         frame = 1;
-        SDL_Delay(prvTickCount + itv - nowTick);
+        SDL_Delay(cast(uint)(prvTickCount + itv - nowTick));
         if (accframe) {
           prvTickCount = SDL_GetTicks();
         } else {
--- a/src/abagames/util/ode/world.d
+++ b/src/abagames/util/ode/world.d
@@ -27,6 +27,8 @@
   dSpaceID _space;
   bool initialized = false;
 
+  private TypeInfo hack1() { return typeid(actor); } //workaround for compiler/linker bug in gdc-4.6 0.29.1-4.6.4-3
+
   public void init() {
     dInitODE();
     world = dWorldCreate();
