WASD to strafe. Cursor Keys to rotate. M to open the map. Q & E to fire portals.
Thanks to @griffpatch for the raycaster engine. I've been working on this for about 3 months, on and off, and completely scrapped it a couple of times. Earlier, I had been trying to use the distance between the ray and portal before teleporting, to reduce distortion, but I couldn't debug it, so I just went with the distortion.