Description: port to D language version 2
  With this patch the code is accepted 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/util/actor.d
+++ b/src/abagames/util/actor.d
@@ -32,7 +32,7 @@
  public:
   T[] actor;
  protected:
-  int actorIdx = 0;
+  ptrdiff_t actorIdx = 0;
  private:
 
   public this() {}
@@ -43,7 +43,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,4 +35,4 @@
   }
 }
 
-alias ArrayIterator!(char[]) StringIterator;
+alias ArrayIterator!(string) StringIterator;
--- 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)
       stderr.writeLine(msg);
@@ -28,24 +29,20 @@
 
   public static void info(double n, bool nline = true) {
     /*if (nline)
-      stderr.writeLine(std.string.toString(n));
+      stderr.writeLine(to!string(n));
     else
-    stderr.writeString(std.string.toString(n) ~ " ");*/
+    stderr.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)
       derr.writeLine(msg);
     else
@@ -63,20 +60,16 @@
 
   public static void info(double n, bool nline = true) {
     if (nline)
-      derr.writeLine(std.string.toString(n));
+      derr.writeLine(to!string(n));
     else
-      derr.writeString(std.string.toString(n) ~ " ");
+      derr.writeString(to!string(n) ~ " ");
   }
 
-  public static void error(char[] msg) {
+  public static void error(string msg) {
     derr.writeLine("Error: " ~ msg);
   }
 
-  public static void error(Exception e) {
-    derr.writeLine("Error: " ~ e.toString());
-  }
-
-  public static void error(Error e) {
+  public static void error(Throwable e) {
     derr.writeLine("Error: " ~ e.toString());
     if (e.next)
       error(e.next);
--- a/src/abagames/util/math.d
+++ b/src/abagames/util/math.d
@@ -13,7 +13,7 @@
 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;
--- 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/mainloop.d
+++ b/src/abagames/util/sdl/mainloop.d
@@ -87,7 +87,7 @@
       frame = cast(int) (nowTick-prvTickCount) / interval;
       if (frame <= 0) {
         frame = 1;
-        SDL_Delay(prvTickCount+interval-nowTick);
+        SDL_Delay(cast(uint)(prvTickCount+interval-nowTick));
         if (accframe) {
           prvTickCount = SDL_GetTicks();
         } else {
--- a/src/abagames/util/sdl/pad.d
+++ b/src/abagames/util/sdl/pad.d
@@ -6,6 +6,7 @@
 module abagames.util.sdl.pad;
 
 private import std.string;
+private import std.conv;
 private import std.stream;
 private import SDL;
 private import abagames.util.sdl.input;
@@ -31,7 +32,7 @@
   public void openJoystick() {
     if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) {
       throw new SDLInitFailedException(
-        "Unable to init SDL joystick: " ~ std.string.toString(SDL_GetError()));
+        "Unable to init SDL joystick: " ~ to!string(SDL_GetError()));
     }
     stick = SDL_JoystickOpen(0);
   }
@@ -157,7 +158,11 @@
   mixin RecordableInput!(PadState);
  private:
 
-  public PadState getState(bool doRecord = true) {
+  public override PadState getState() {
+    return getState(true);
+  }
+
+  public PadState getState(bool doRecord) {
     PadState s = super.getState();
     if (doRecord)
       record(s);
--- 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);
@@ -55,7 +56,7 @@
   public void screenResized() {
     if (SDL_SetVideoMode(width, height, 0, _videoFlags) == null) {
       throw new Exception
-        ("Unable to resize SDL screen: " ~ std.string.toString(SDL_GetError()));
+        ("Unable to resize SDL screen: " ~ to!string(SDL_GetError()));
     }
 
     glViewport(0, 0, _width, _height);
@@ -95,10 +96,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/val-and-rick/sounds/musics";
+  static string dir = "/usr/share/games/val-and-rick/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/val-and-rick/sounds/chunks";
+  static string dir = "/usr/share/games/val-and-rick/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/val-and-rick/images/";
-  static SDL_Surface*[char[]] surface;
+  static string imagesDir = "/usr/share/games/val-and-rick/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) != null) {
       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;
@@ -97,13 +97,13 @@
         }
         glBindTexture(GL_TEXTURE_2D, num + ti);
         gluBuild2DMipmaps(GL_TEXTURE_2D, 4, panelWidth, panelHeight,
-                          GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
+                          GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels.ptr);
         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
         if (maskColor != 0xffffffffu) {
           glBindTexture(GL_TEXTURE_2D, maskNum + ti);
           gluBuild2DMipmaps(GL_TEXTURE_2D, 4, panelWidth, panelHeight,
-                            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, maskPixels);
+                            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, maskPixels.ptr);
           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
         }
--- 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 = split(line, separator);
-      foreach (char[] s; spl) {
-	char[] r = strip(s);
+      string[] spl = 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.
@@ -201,8 +202,8 @@
       return false;
   }
 
-  public char[] toString() {
-    return "(" ~ std.string.toString(x) ~ ", " ~ std.string.toString(y) ~ ")";
+  public override string toString() {
+    return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ")";
   }
 }
 
--- a/src/abagames/vr/barrage.d
+++ b/src/abagames/vr/barrage.d
@@ -23,25 +23,27 @@
  */
 public class BarrageManager {
  private:
-  static BulletMLParserTinyXML *parser[char[]][char[]];
-  static const char[] BARRAGE_DIR_NAME = "/usr/share/games/val-and-rick/barrage";
+  static BulletMLParserTinyXML *parser[string][string];
+  static const string BARRAGE_DIR_NAME = "/usr/share/games/val-and-rick/barrage";
 
   public static void load() {
-    char[][] dirs = listdir(BARRAGE_DIR_NAME);
-    foreach (char[] dirName; dirs) {
-      char[][] files = listdir(BARRAGE_DIR_NAME ~ "/" ~ dirName);
+    auto dirs = dirEntries(BARRAGE_DIR_NAME, SpanMode.shallow);
+    foreach (string fullDirName; dirs) {
+      string dirName = baseName(fullDirName);
+      auto files = dirEntries(fullDirName, SpanMode.shallow);
       parser[dirName] = null;
-      foreach (char[] fileName; files) {
-        if (getExt(fileName) != "xml")
+      foreach (string fullFileName; files) {
+        string fileName = baseName(fullFileName);
+        if (extension(fileName) != ".xml")
           continue;
         parser[dirName][fileName] = getInstance(dirName, fileName);
       }
     }
   }
 
-  public static BulletMLParserTinyXML* getInstance(char[] dirName, char[] fileName) {
+  public static BulletMLParserTinyXML* getInstance(string dirName, string fileName) {
     if (!parser[dirName][fileName]) {
-      char[] barrageName = dirName ~ "/" ~ fileName;
+      string barrageName = dirName ~ "/" ~ fileName;
       Logger.info("Loading BulletML: " ~ barrageName);
       parser[dirName][fileName] = 
         BulletMLParserTinyXML_new(std.string.toStringz(BARRAGE_DIR_NAME ~ "/" ~ barrageName));
@@ -50,7 +52,7 @@
     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;
@@ -59,7 +61,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/vr/boot.d
+++ b/src/abagames/vr/boot.d
@@ -6,6 +6,7 @@
 module abagames.vr.boot;
 
 private import std.string;
+private import std.conv;
 private import std.stream;
 private import std.c.stdlib;
 private import abagames.util.logger;
@@ -51,10 +52,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;
     }
@@ -63,12 +64,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) {
   //Reflection.init(args[0]);
   screen = new Screen;
   pad = new RecordablePad;
@@ -85,22 +86,22 @@
   }
   try {
     mainLoop.loop();
-  } catch (Object o) {
+  } catch (Throwable o) {
     Logger.info(o.toString());
     //Logger.info(Reflection.stackTrace());
     try {
       gameManager.saveErrorReplay();
-    } catch (Object o1) {}
+    } catch (Throwable o1) {}
     throw o;
   }
   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":
@@ -109,7 +110,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");
@@ -123,7 +124,7 @@
         throw new Exception("Invalid options");
       }
       i++;
-      float l = cast(float) std.string.atoi(args[i]) / 100;
+      float l = cast(float) to!int(args[i]) / 100;
       if (l < 0 || l > 1) {
         usage(progName);
         throw new Exception("Invalid options");
@@ -142,9 +143,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;
@@ -167,17 +168,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] [-fullscreen] [-res x y] [-brightness [0-100]] [-luminosity [0-100]] [-nosound] [-reverse] [-nowait]");
 }
--- a/src/abagames/vr/enemy.d
+++ b/src/abagames/vr/enemy.d
@@ -46,11 +46,8 @@
   EnemyState _state;
   bool damaged;
 
-  public static this() {
-    rand = new Rand;
-  }
-
   public static void setRandSeed(long seed) {
+    if (rand is null) rand = new Rand;
     rand.setSeed(seed);
   }
 
@@ -200,7 +197,7 @@
 
   public this() {
     pos = new Vector;
-    foreach (inout Vector bp; bitPos)
+    foreach (ref Vector bp; bitPos)
       bp = new Vector;
   }
 
@@ -422,7 +419,7 @@
     pos = new Vector;
     ppos = new Vector;
     vel = new Vector;
-    foreach (inout EnemyBit eb; enemyBit)
+    foreach (ref EnemyBit eb; enemyBit)
       eb = new EnemyBit;
   }
 
@@ -431,11 +428,11 @@
     this.appType = appType;
     bool validPos = false;
     for (int i = 0 ; i < 8 ; i++) {
-      switch (appType) {
+      switch (appType) { default: break;
       case AppearanceType.TOP:
       case AppearanceType.TOP_LEFT:
       case AppearanceType.TOP_RIGHT:
-        switch (appType) {
+        switch (appType) { default: break;
         case AppearanceType.TOP:
           pos.x = rand.nextSignedFloat(field.size.x);
           break;
@@ -682,7 +679,7 @@
     return true;
   }
 
-  public bool move(EnemyState es) {
+  public override bool move(EnemyState es) {
     super.move(es);
     es.pos.x += sin(es.deg) * es.speed;
     es.pos.y += cos(es.deg) * es.speed;
@@ -697,7 +694,7 @@
       es.pos.x += sin(es.deg) * es.speed * 2;
       es.pos.y += cos(es.deg) * es.speed * 2;
     }
-    switch (es.state) {
+    switch (es.state) { default: break;
     case MoveState.MOVING:
       es.speed += (maxSpeed - es.speed) * accel;
       es.cnt--;
@@ -741,7 +738,7 @@
     return true;
   }
 
-  public bool move(EnemyState es) {
+  public override bool move(EnemyState es) {
     super.move(es);
     es.pos.x += sin(es.deg) * speed;
     es.pos.y += cos(es.deg) * speed;
@@ -778,7 +775,7 @@
   public this(BulletActorPool bullets, Field field, Ship ship) {
     super(bullets, field, ship, EnemyType.BLOCK,
           BitmapShape.ground, 12, 2, AnimationType.BACKANDFORTH, 30, 18);
-    foreach (inout EnemyBitSpec bs; bitSpec)
+    foreach (ref EnemyBitSpec bs; bitSpec)
       bs = new EnemyBitSpec;
   }
 
@@ -800,7 +797,7 @@
     }
   }
 
-  public bool move(EnemyState es) {
+  public override bool move(EnemyState es) {
     super.move(es);
     es.pos.y -= field.lastScrollY;
     if  (es.pos.y <= -field.outerSize.y)
@@ -808,7 +805,7 @@
     return true;
   }
 
-  public void destroyed(EnemyState es, Shot shot, ExplosionPool explosions, ParticlePool particles) {
+  public override void destroyed(EnemyState es, Shot shot, ExplosionPool explosions, ParticlePool particles) {
     Explosion ep = explosions.getInstance();
     if (ep)
       ep.set(es.pos, 0, 0, 30, 3);
@@ -852,7 +849,7 @@
     return true;
   }
 
-  public bool move(EnemyState es) {
+  public override bool move(EnemyState es) {
     super.move(es);
     es.pos.x += es.vel.x;
     es.pos.y += es.vel.y;
@@ -862,7 +859,7 @@
       es.pos.y -= field.lastScrollY * SKY_SCROLL_RATIO;
     if  (!field.checkInOuterField(es.pos))
       return false;
-    switch (es.state) {
+    switch (es.state) { default: break;
     case MoveState.APPROACHING:
       if (fabs(es.pos.x - ship.pos.x) < 4.4f) {
         es.state = MoveState.SEPARATION;
--- a/src/abagames/vr/field.d
+++ b/src/abagames/vr/field.d
@@ -62,7 +62,7 @@
     for (int i = 0; i < 2; i++)
       spacePattern[rand.nextInt(BLOCK_SIZE_X / 4)][rand.nextInt(BLOCK_SIZE_Y / 4)] = 2;
     panelPos = new Vector[SCREEN_BLOCK_SIZE_X * NEXT_BLOCK_AREA_SIZE];
-    foreach (inout Vector pp; panelPos)
+    foreach (ref Vector pp; panelPos)
       pp = new Vector;
   }
 
@@ -302,7 +302,7 @@
 
   private void addGround(int type) {
     int cx;
-    switch (type) {
+    switch (type) { default: break;
     case 0:
       cx = rand.nextInt(cast(int) (BLOCK_SIZE_X * 0.4f)) + cast(int) (BLOCK_SIZE_X * 0.1f);
       break;
--- a/src/abagames/vr/gamemanager.d
+++ b/src/abagames/vr/gamemanager.d
@@ -175,13 +175,13 @@
   private void saveLastReplay() {
     try {
       inGameState.saveReplay("last.rpl");
-    } catch (Object o) {}
+    } catch (Throwable o) {}
   }
 
   private void loadLastReplay() {
     try {
       inGameState.loadReplay("last.rpl");
-    } catch (Object o) {
+    } catch (Throwable o) {
       inGameState.resetReplay();
     }
   }
@@ -466,11 +466,11 @@
     distance += dist;
   }
 
-  public void saveReplay(char[] fileName) {
+  public void saveReplay(string fileName) {
     _replayData.save(fileName);
   }
 
-  public void loadReplay(char[] fileName) {
+  public void loadReplay(string fileName) {
     _replayData = new ReplayData;
     _replayData.load(fileName);
   }
--- a/src/abagames/vr/letter.d
+++ b/src/abagames/vr/letter.d
@@ -96,7 +96,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, int cl = 0,
                                 bool rev = false, float od = 0) {
     lx += LETTER_WIDTH * s / 2;
@@ -104,7 +104,7 @@
     float x = lx;
     int idx;
     float ld;
-    switch (d) {
+    switch (d) { default: break;
     case Direction.TO_RIGHT:
       ld = 0;
       break;
@@ -128,7 +128,7 @@
           drawLetter(idx, x, y, s, ld, cl);
       }
       if (od == 0) {
-        switch(d) {
+        switch(d) { default: break;
         case Direction.TO_RIGHT:
           x += s * LETTER_WIDTH;
           break;
@@ -156,7 +156,7 @@
     int n = num;
     float x = lx;
     float ld;
-    switch (d) {
+    switch (d) { default: break;
     case Direction.TO_RIGHT:
       ld = 0;
       break;
@@ -173,7 +173,7 @@
     int digit = dg;
     for (;;) {
       drawLetter(n % 10, x, y, s, ld, cl);
-      switch(d) {
+      switch(d) { default: break;
       case Direction.TO_RIGHT:
         x -= s * LETTER_WIDTH;
         break;
@@ -230,7 +230,7 @@
         n /= 6;
       }
       if ((i & 1) == 1 || i == 0) {
-        switch (i) {
+        switch (i) { default: break;
         case 3:
           drawLetter(41, x + s * 1.16f, y, s, Direction.TO_RIGHT, st);
           break;
--- a/src/abagames/vr/prefmanager.d
+++ b/src/abagames/vr/prefmanager.d
@@ -8,6 +8,7 @@
 private import std.stream;
 private import std.c.stdlib;
 private import std.string;
+private import std.conv;
 private import std.file;
 private import abagames.util.prefmanager;
 private import abagames.vr.ship;
@@ -18,19 +19,19 @@
 public class PrefManager: abagames.util.prefmanager.PrefManager {
  private:
   static const int VERSION_NUM = 10;
-  static const char[] PREF_FILE = "val-and-rick.prf";
+  static const string PREF_FILE = "val-and-rick.prf";
   PrefData _prefData;
 
   public this() {
     _prefData = new PrefData;
   }
 
-  public static char[] pref_dir()
+  public static string pref_dir()
   {
-    char * home = getenv("HOME");
+    const(char)* home = getenv("HOME");
     if (home is null)
       throw new Error("HOME environment variable not defined");
-    char[] dir = std.string.toString(home) ~ "/.val-and-rick";
+    string dir = to!string(home) ~ "/.val-and-rick";
     try {
       mkdir(dir);
     } catch (FileException e) {
@@ -39,7 +40,7 @@
   }
 
   public void load() {
-    auto File fd = new File;
+    scope File fd = new File;
     try {
       int ver;
       fd.open(pref_dir() ~ "/" ~ PREF_FILE);
@@ -47,7 +48,7 @@
       if (ver != VERSION_NUM)
         throw new Error("Wrong version num");
       _prefData.load(fd);
-    } catch (Object e) {
+    } catch (Throwable e) {
       _prefData.init();
     } finally {
       if (fd.isOpen())
@@ -56,7 +57,7 @@
   }
 
   public void save() {
-    auto File fd = new File;
+    scope File fd = new File;
     fd.create(pref_dir() ~ "/" ~ PREF_FILE);
     fd.write(VERSION_NUM);
     _prefData.save(fd);
--- a/src/abagames/vr/replay.d
+++ b/src/abagames/vr/replay.d
@@ -20,8 +20,8 @@
   long seed;
  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);
@@ -29,8 +29,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/vr/screen.d
+++ b/src/abagames/vr/screen.d
@@ -18,18 +18,15 @@
  */
 public class Screen: Screen3D {
  private:
-  const char[] CAPTION = "Val & Rick";
+  const string CAPTION = "Val & Rick";
   static Rand rand;
   LuminousScreen luminousScreen;
   float _luminosity = 0;
   int screenShakeCnt;
   float screenShakeIntense;
 
-  public static this() {
-    rand = new Rand;
-  }
-
   public static void setRandSeed(long seed) {
+    if (rand is null) rand = new Rand;
     rand.setSeed(seed);
   }
 
@@ -77,7 +74,7 @@
       luminousScreen.draw();
   }
 
-  public void resized(int width, int height) {
+  public override void resized(int width, int height) {
     if (luminousScreen)
       luminousScreen.resized(width, height);
     super.resized(width, height);
--- a/src/abagames/vr/ship.d
+++ b/src/abagames/vr/ship.d
@@ -109,7 +109,7 @@
 
   public void setShots(ShotPool shots) {
     this.shots = shots;
-    foreach (inout ShipShadow ss; shadow)
+    foreach (ref ShipShadow ss; shadow)
       ss = new ShipShadow(_shape, shots);
   }
 
@@ -315,7 +315,7 @@
           s.set(_pos, deg);
         fireCnt = FIRE_INTERVAL;
         float td;
-        switch (fireSprCnt % 2) {
+        switch (fireSprCnt % 2) { default: break;
         case 0:
           td = fireSprDeg * (fireSprCnt / 2 % 4 + 1) * 0.2f;
           fireEvenShadow = true;
--- a/src/abagames/vr/soundmanager.d
+++ b/src/abagames/vr/soundmanager.d
@@ -16,27 +16,31 @@
  */
 public class SoundManager: abagames.util.sdl.sound.SoundManager {
  private static:
-  char[][] seFileName =
+  string[] seFileName =
     ["shot.wav", "zako_dest.wav", "large_dest.wav", "ship_dest.wav", "blaster.wav",
      "crystal.wav", "rocket.wav"];
   int[] seChannel =
     [0, 1, 2, 3, 4, 5, 6, 7];
-  Music[char[]] bgm;
-  Chunk[char[]] se;
+  Music[string] bgm;
+  Chunk[string] se;
   bool bgmDisabled = false;
   bool seDisabled = false;
 
+  private TypeInfo hack1() { return typeid(se); } //workaround for compiler/linker bug in gdc-4.6 0.29.1-4.6.4-3
+  private TypeInfo hack2() { return typeid(bgm); } //workaround for compiler/linker bug in gdc-4.6 0.29.1-4.6.4-3
+
   public static void loadSounds() {
     bgm = loadMusics();
     se = loadChunks();
   }
 
-  private static Music[char[]] loadMusics() {
-    Music[char[]] musics;
-    char[][] files = listdir(Music.dir);
-    foreach (char[] fileName; files) {
-      char[] ext = getExt(fileName);
-      if (ext != "ogg" && ext != "wav")
+  private static Music[string] loadMusics() {
+    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);
@@ -46,10 +50,10 @@
     return musics;
   }
 
-  private static Chunk[char[]] loadChunks() {
-    Chunk[char[]] chunks;
+  private static Chunk[string] loadChunks() {
+    Chunk[string] chunks;
     int i = 0;
-    foreach (char[] fileName; seFileName) {
+    foreach (string fileName; seFileName) {
       Chunk chunk = new Chunk();
       chunk.load(fileName, seChannel[i]);
       chunks[fileName] = chunk;
@@ -59,7 +63,7 @@
     return chunks;
   }
 
-  public static void playBgm(char[] name) {
+  public static void playBgm(string name) {
     if (bgmDisabled)
       return;
     Music.haltMusic();
@@ -74,7 +78,7 @@
     Music.haltMusic();
   }
 
-  public static void playSe(char[] name) {
+  public static void playSe(string name) {
     if (seDisabled)
       return;
     se[name].play();
--- a/src/abagames/vr/stagemanager.d
+++ b/src/abagames/vr/stagemanager.d
@@ -45,7 +45,7 @@
     this.bullets = bullets;
     rand = new Rand;
     zakoApp = new ZakoAppearance[2];
-    foreach (inout ZakoAppearance za; zakoApp)
+    foreach (ref ZakoAppearance za; zakoApp)
       za = new ZakoAppearance;
   }
 
@@ -108,7 +108,7 @@
     if (apn > 10)
       apn = 10;
     zakoApp[1].set(null, 0, null, null);
-    switch (rand.nextInt(apn)) {
+    switch (rand.nextInt(apn)) { default: break;
     case 0:
     case 1:
     case 2:
@@ -152,7 +152,7 @@
       eb1Spec.bitNum = 1;
     float br = rank / eb1Spec.bitNum;
     int type;
-    switch (rand.nextInt(4)) {
+    switch (rand.nextInt(4)) { default: break;
     case 0:
     case 1:
       type = 0;
@@ -168,7 +168,7 @@
     float radInc = 0.5f + rand.nextFloat(0.25f);
     float ad = PI * 2;
     float a, av, dv, s, sv;
-    switch (type) {
+    switch (type) { default: break;
     case 0:
       if (rand.nextInt(5) == 0)
         ad = PI / 2 + rand.nextFloat(PI / 2);
@@ -195,7 +195,7 @@
       ebs.moveType = type;
       ebs.radiusBase = rad;
       float sr;
-      switch (type) {
+      switch (type) { default: break;
       case 0:
         ebs.alignDeg = ad;
         ebs.num = 4 + rand.nextInt(6);
@@ -267,7 +267,7 @@
       BulletMLParserTinyXML*[] ps = BarrageManager.getInstanceList("morph");
       while (morphRank > 1) {
         morphRank /= 3;
-        int pi = rand.nextInt(ps.length);
+        int pi = rand.nextInt(cast(int)ps.length);
         float mr = morphRank;
         if (mr > 0.75f)
           mr = 0.75f + rand.nextFloat(0.25f);
@@ -313,7 +313,7 @@
       BulletMLParserTinyXML*[] ps = BarrageManager.getInstanceList("morph");
       while (morphRank > 1) {
         morphRank /= 3;
-        int pi = rand.nextInt(ps.length);
+        int pi = rand.nextInt(cast(int)ps.length);
         float mr = morphRank;
         if (mr > 0.75f)
           mr = 0.75f + rand.nextFloat(0.25f);
--- a/src/abagames/util/bulletml/bullet.d
+++ b/src/abagames/util/bulletml/bullet.d
@@ -28,11 +28,8 @@
   BulletMLRunner* runner;
   float _rank;
 
-  public static this() {
-    rand = new Rand;
-  }
-
   public static void setRandSeed(long s) {
+    if (rand is null) rand = new Rand;
     rand.setSeed(s);
   }
 
--- a/src/abagames/util/sdl/luminous.d
+++ b/src/abagames/util/sdl/luminous.d
@@ -33,9 +33,9 @@
   }
 
   private void makeLuminousTexture() {
-    uint *data = td;
+    uint *data = td.ptr;
     int i;
-    memset(data, 0, luminousTextureWidth * luminousTextureHeight * 4 * uint.sizeof);
+    td[] = 0;
     glGenTextures(1, &luminousTexture);
     glBindTexture(GL_TEXTURE_2D, luminousTexture);
     glTexImage2D(GL_TEXTURE_2D, 0, 4, luminousTextureWidth, luminousTextureHeight, 0,
--- a/src/abagames/vr/particle.d
+++ b/src/abagames/vr/particle.d
@@ -29,11 +29,8 @@
   float lumAlp;
   int cnt;
 
-  public static this() {
-    rand = new Rand;
-  }
-
   public static void setRandSeed(long seed) {
+    if (rand is null) rand = new Rand;
     rand.setSeed(seed);
   }
 
--- a/src/abagames/vr/bulletactorpool.d
+++ b/src/abagames/vr/bulletactorpool.d
@@ -104,7 +104,7 @@
     cnt++;
   }
 
-  public void draw() {
+  public override void draw() {
     foreach (BulletActor ba; actor)
       if (ba.exists)
         ba.draw();
