<commit_before>/**
 * @author dmarcos / https://github.com/dmarcos
 *
 * It handles stereo rendering
 * If mozGetVRDevices and getVRDevices APIs are not available it gracefuly falls back to a
 * regular renderer
 *
 * The HMD supported is the Oculus DK1 and The Web API doesn't currently allow
 * to query for the display resolution (only the chrome API allows it).
 * The dimensions of the screen are temporarly hardcoded (1280 x 800).
 *
 * For VR mode to work it has to be used with the Oculus enabled builds of Firefox or Chrome:
 *
 * Firefox:
 *
 * OSX: http://people.mozilla.com/~vladimir/vr/firefox-33.0a1.en-US.mac.dmg
 * WIN: http://people.mozilla.com/~vladimir/vr/firefox-33.0a1.en-US.win64-x86_64.zip
 *
 * Chrome builds:
 *
 * https://drive.google.com/folderview?id=0BzudLt22BqGRbW9WTHMtOWMzNjQ&usp=sharing#list
 *
 */
THREE.VREffect = function ( renderer, done, config ) {

	var cameraLeft = new THREE.PerspectiveCamera();
	var cameraRight = new THREE.PerspectiveCamera();

	this._renderer = renderer;
	this._renderScale = 1.1;

	this._init = function() {
		var self = this;
		if ( !navigator.getVRDevices ) {
			if ( config ) {
				setupConfig( config );
				return;
			}

			if ( done ) {
				done("Your browser is not VR Ready");
			}
			return;
		}
		navigator.getVRDevices().then( gotVRDevices );

		function gotVRDevices( devices ) {
			var vrHMD;
			var error;
			for ( var i = 0; i < devices.length; ++i ) {
				if ( devices[i] instanceof HMDVRDevice ) {
					vrHMD = devices[i];
					self._vrHMD = vrHMD;
					self.leftEyeTranslation = vrHMD.getEyeTranslation( "left" );
					self.rightEyeTranslation = vrHMD.getEyeTranslation( "right" );
					self.leftEyeFOV = vrHMD.getRecommendedEyeFieldOfView( "left" );
					self.rightEyeFOV = vrHMD.getRecommendedEyeFieldOfView( "right" );

					break; // We keep the first we encounter
				}
			}
			if ( done ) {
				if ( !vrHMD ) {
					error = 'HMD not available';
				}
				done( error );
			}
		}

		function setupConfig( config ) {
			self.stereo = config.stereo || true;

			var separation = 0.032;

			self.leftEyeTranslation = { x: -separation };
			self.rightEyeTranslation = { x: separation };

			self.leftEyeFOV = {
				downDegrees: 50,
				leftDegrees: 47,
				rightDegrees: 47,
				upDegrees: 53
			};
			self.rightEyeFOV = {
				downDegrees: 53,
				leftDegrees: 47,
				rightDegrees: 47,
				upDegrees: 53
			};
		}
	};

	this._init();

	this.render = function ( scene, camera ) {
		var renderer = this._renderer;
		var vrHMD = this._vrHMD;
		renderer.enableScissorTest( false );
		// VR render mode if HMD is available
		if ( vrHMD || this.stereo ) {
			this.renderStereo.apply( this, arguments );
			return;
		}
		// Regular render mode if not HMD
		renderer.render.apply( this._renderer , arguments );
	};

	this.setRenderScale = function ( scale ) {
		var renderer = this._renderer;
		this._renderScale = scale;
		renderer.setSize( 1920*this._renderScale, 1080*this._renderScale, false );
	};

	this.getRenderScale = function( ) {
		return this._renderScale;
	};

	this.renderStereo = function( scene, camera, renderTarget, forceClear ) {

		var leftEyeTranslation = this.leftEyeTranslation;
		var rightEyeTranslation = this.rightEyeTranslation;
		var renderer = this._renderer;
		var rendererWidth = renderer.domElement.width / renderer.devicePixelRatio;
		var rendererHeight = renderer.domElement.height / renderer.devicePixelRatio;
		var eyeDivisionLine = rendererWidth / 2;

		renderer.enableScissorTest( true );
		renderer.clear();

		if ( camera.parent === undefined ) {
			camera.updateMatrixWorld();
		}

		cameraLeft.projectionMatrix = this.FovToProjection( this.leftEyeFOV, true, camera.near, camera.far );
		cameraRight.projectionMatrix = this.FovToProjection( this.rightEyeFOV, true, camera.near, camera.far );

		camera.matrixWorld.decompose( cameraLeft.position, cameraLeft.quaternion, cameraLeft.scale );
		camera.matrixWorld.decompose( cameraRight.position, cameraRight.quaternion, cameraRight.scale );

		cameraLeft.translateX( leftEyeTranslation.x );
		cameraRight.translateX( rightEyeTranslation.x );

		// render left eye
		renderer.setViewport( 0, 0, eyeDivisionLine, rendererHeight );
		renderer.setScissor( 0, 0, eyeDivisionLine, rendererHeight );
		renderer.render( scene, cameraLeft );

		// render right eye
		renderer.setViewport( eyeDivisionLine, 0, eyeDivisionLine, rendererHeight );
		renderer.setScissor( eyeDivisionLine, 0, eyeDivisionLine, rendererHeight );
		renderer.render( scene, cameraRight );

		renderer.enableScissorTest( false );
	};

	this.setFullScreen = function( enable ) {
		var renderer = this._renderer;
		var vrHMD = this._vrHMD;
		var canvasOriginalSize = this._canvasOriginalSize;
		if (!vrHMD) {
			return;
		}
		// If state doesn't change we do nothing
		if ( enable === this._fullScreen ) {
			return;
		}
		this._fullScreen = !!enable;

		// VR Mode disabled
		if ( !enable ) {
			// Restores canvas original size
			renderer.setSize( canvasOriginalSize.width, canvasOriginalSize.height );
			return;
		}
		// VR Mode enabled
		this._canvasOriginalSize = {
			width: renderer.domElement.width,
			height: renderer.domElement.height
		};

		this.setRenderScale( this._renderScale );
		this.startFullscreen();
	};

	this.startFullscreen = function() {
		var self = this;
		var renderer = this._renderer;
		var vrHMD = this._vrHMD;
		var canvas = renderer.domElement;
		var fullScreenChange =
			canvas.mozRequestFullScreen? 'mozfullscreenchange' : 'webkitfullscreenchange';

		document.addEventListener( fullScreenChange, onFullScreenChanged, false );
		function onFullScreenChanged() {
			if ( !document.mozFullScreenElement && !document.webkitFullScreenElement ) {
				self.setFullScreen( false );
			}
		}
		if ( canvas.mozRequestFullScreen ) {
			canvas.mozRequestFullScreen( { vrDisplay: vrHMD } );
		} else {
			canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } );
		}
	};

	this.getTimewarp = function() {
		if ( this._vrHMD && this._vrHMD.getTimewarp ) {
			this._vrHMD.getTimewarp();
		}
	};

	this.setTimewarp = function( val ) {
		if ( this._vrHMD && this._vrHMD.setTimewarp ) {
			this._vrHMD.setTimewarp( val );
		}
	};

	this.FovToNDCScaleOffset = function( fov ) {
		var pxscale = 2.0 / (fov.leftTan + fov.rightTan);
		var pxoffset = (fov.leftTan - fov.rightTan) * pxscale * 0.5;
		var pyscale = 2.0 / (fov.upTan + fov.downTan);
		var pyoffset = (fov.upTan - fov.downTan) * pyscale * 0.5;
		return { scale: [pxscale, pyscale], offset: [pxoffset, pyoffset] };
	};

	this.FovPortToProjection = function( fov, rightHanded /* = true */, zNear /* = 0.01 */, zFar /* = 10000.0 */ )
	{
		rightHanded = rightHanded === undefined ? true : rightHanded;
		zNear = zNear === undefined ? 0.01 : zNear;
		zFar = zFar === undefined ? 10000.0 : zFar;

		var handednessScale = rightHanded ? -1.0 : 1.0;

		// start with an identity matrix
		var mobj = new THREE.Matrix4();
		var m = mobj.elements;

		// and with scale/offset info for normalized device coords
		var scaleAndOffset = this.FovToNDCScaleOffset(fov);

		// X result, map clip edges to [-w,+w]
		m[0*4+0] = scaleAndOffset.scale[0];
		m[0*4+1] = 0.0;
		m[0*4+2] = scaleAndOffset.offset[0] * handednessScale;
		m[0*4+3] = 0.0;

		// Y result, map clip edges to [-w,+w]
		// Y offset is negated because this proj matrix transforms from world coords with Y=up,
		// but the NDC scaling has Y=down (thanks D3D?)
		m[1*4+0] = 0.0;
		m[1*4+1] = scaleAndOffset.scale[1];
		m[1*4+2] = -scaleAndOffset.offset[1] * handednessScale;
		m[1*4+3] = 0.0;

		// Z result (up to the app)
		m[2*4+0] = 0.0;
		m[2*4+1] = 0.0;
		m[2*4+2] = zFar / (zNear - zFar) * -handednessScale;
		m[2*4+3] = (zFar * zNear) / (zNear - zFar);

		// W result (= Z in)
		m[3*4+0] = 0.0;
		m[3*4+1] = 0.0;
		m[3*4+2] = handednessScale;
		m[3*4+3] = 0.0;

		mobj.transpose();

		return mobj;
	};

	this.FovToProjection = function( fov, rightHanded /* = true */, zNear /* = 0.01 */, zFar /* = 10000.0 */ )
	{
		var DEG2RAD = Math.PI / 180.0;

		var fovPort = {
			upTan: Math.tan(fov.upDegrees * DEG2RAD),
			downTan: Math.tan(fov.downDegrees * DEG2RAD),
			leftTan: Math.tan(fov.leftDegrees * DEG2RAD),
			rightTan: Math.tan(fov.rightDegrees * DEG2RAD)
		};
		return this.FovPortToProjection(fovPort, rightHanded, zNear, zFar);
	};

};<commit_msg>post FS renderscale fix<commit_after>/**
 * @author dmarcos / https://github.com/dmarcos
 *
 * It handles stereo rendering
 * If mozGetVRDevices and getVRDevices APIs are not available it gracefuly falls back to a
 * regular renderer
 *
 * The HMD supported is the Oculus DK1 and The Web API doesn't currently allow
 * to query for the display resolution (only the chrome API allows it).
 * The dimensions of the screen are temporarly hardcoded (1280 x 800).
 *
 * For VR mode to work it has to be used with the Oculus enabled builds of Firefox or Chrome:
 *
 * Firefox:
 *
 * OSX: http://people.mozilla.com/~vladimir/vr/firefox-33.0a1.en-US.mac.dmg
 * WIN: http://people.mozilla.com/~vladimir/vr/firefox-33.0a1.en-US.win64-x86_64.zip
 *
 * Chrome builds:
 *
 * https://drive.google.com/folderview?id=0BzudLt22BqGRbW9WTHMtOWMzNjQ&usp=sharing#list
 *
 */
THREE.VREffect = function ( renderer, done, config ) {

	var cameraLeft = new THREE.PerspectiveCamera();
	var cameraRight = new THREE.PerspectiveCamera();

	this._renderer = renderer;
	this._renderScale = 1.1;

	this._init = function() {
		var self = this;
		if ( !navigator.getVRDevices ) {
			if ( config ) {
				setupConfig( config );
				return;
			}

			if ( done ) {
				done("Your browser is not VR Ready");
			}
			return;
		}
		navigator.getVRDevices().then( gotVRDevices );

		function gotVRDevices( devices ) {
			var vrHMD;
			var error;
			for ( var i = 0; i < devices.length; ++i ) {
				if ( devices[i] instanceof HMDVRDevice ) {
					vrHMD = devices[i];
					self._vrHMD = vrHMD;
					self.leftEyeTranslation = vrHMD.getEyeTranslation( "left" );
					self.rightEyeTranslation = vrHMD.getEyeTranslation( "right" );
					self.leftEyeFOV = vrHMD.getRecommendedEyeFieldOfView( "left" );
					self.rightEyeFOV = vrHMD.getRecommendedEyeFieldOfView( "right" );

					break; // We keep the first we encounter
				}
			}
			if ( done ) {
				if ( !vrHMD ) {
					error = 'HMD not available';
				}
				done( error );
			}
		}

		function setupConfig( config ) {
			self.stereo = config.stereo || true;

			var separation = 0.032;

			self.leftEyeTranslation = { x: -separation };
			self.rightEyeTranslation = { x: separation };

			self.leftEyeFOV = {
				downDegrees: 50,
				leftDegrees: 47,
				rightDegrees: 47,
				upDegrees: 53
			};
			self.rightEyeFOV = {
				downDegrees: 53,
				leftDegrees: 47,
				rightDegrees: 47,
				upDegrees: 53
			};
		}
	};

	this._init();

	this.render = function ( scene, camera ) {
		var renderer = this._renderer;
		var vrHMD = this._vrHMD;
		renderer.enableScissorTest( false );
		// VR render mode if HMD is available
		if ( vrHMD || this.stereo ) {
			this.renderStereo.apply( this, arguments );
			return;
		}
		// Regular render mode if not HMD
		renderer.render.apply( this._renderer , arguments );
	};

	this.setRenderScale = function ( scale ) {
		this._renderScale = scale;
		this._renderer.setSize( 1920*this._renderScale, 1080*this._renderScale, false );
	};

	this.getRenderScale = function( ) {
		return this._renderScale;
	};

	this.renderStereo = function( scene, camera, renderTarget, forceClear ) {

		var leftEyeTranslation = this.leftEyeTranslation;
		var rightEyeTranslation = this.rightEyeTranslation;
		var renderer = this._renderer;
		var rendererWidth = renderer.domElement.width / renderer.devicePixelRatio;
		var rendererHeight = renderer.domElement.height / renderer.devicePixelRatio;
		var eyeDivisionLine = rendererWidth / 2;

		renderer.enableScissorTest( true );
		renderer.clear();

		if ( camera.parent === undefined ) {
			camera.updateMatrixWorld();
		}

		cameraLeft.projectionMatrix = this.FovToProjection( this.leftEyeFOV, true, camera.near, camera.far );
		cameraRight.projectionMatrix = this.FovToProjection( this.rightEyeFOV, true, camera.near, camera.far );

		camera.matrixWorld.decompose( cameraLeft.position, cameraLeft.quaternion, cameraLeft.scale );
		camera.matrixWorld.decompose( cameraRight.position, cameraRight.quaternion, cameraRight.scale );

		cameraLeft.translateX( leftEyeTranslation.x );
		cameraRight.translateX( rightEyeTranslation.x );

		// render left eye
		renderer.setViewport( 0, 0, eyeDivisionLine, rendererHeight );
		renderer.setScissor( 0, 0, eyeDivisionLine, rendererHeight );
		renderer.render( scene, cameraLeft );

		// render right eye
		renderer.setViewport( eyeDivisionLine, 0, eyeDivisionLine, rendererHeight );
		renderer.setScissor( eyeDivisionLine, 0, eyeDivisionLine, rendererHeight );
		renderer.render( scene, cameraRight );

		renderer.enableScissorTest( false );
	};

	this.setFullScreen = function( enable ) {
		var renderer = this._renderer;
		var vrHMD = this._vrHMD;
		var canvasOriginalSize = this._canvasOriginalSize;
		if (!vrHMD) {
			return;
		}
		// If state doesn't change we do nothing
		if ( enable === this._fullScreen ) {
			return;
		}
		this._fullScreen = !!enable;

		// VR Mode disabled
		if ( !enable ) {
			// Restores canvas original size
			renderer.setSize( canvasOriginalSize.width, canvasOriginalSize.height );
			return;
		}
		// VR Mode enabled
		this._canvasOriginalSize = {
			width: renderer.domElement.width,
			height: renderer.domElement.height
		};

		this.startFullscreen();

		setTimeout( this.setRenderScale.bind( this, this._renderScale ), 1000 );
	};

	this.startFullscreen = function() {
		var self = this;
		var renderer = this._renderer;
		var vrHMD = this._vrHMD;
		var canvas = renderer.domElement;
		var fullScreenChange =
			canvas.mozRequestFullScreen? 'mozfullscreenchange' : 'webkitfullscreenchange';

		document.addEventListener( fullScreenChange, onFullScreenChanged, false );
		function onFullScreenChanged() {
			if ( !document.mozFullScreenElement && !document.webkitFullScreenElement ) {
				self.setFullScreen( false );
			}
		}
		if ( canvas.mozRequestFullScreen ) {
			canvas.mozRequestFullScreen( { vrDisplay: vrHMD } );
		} else {
			canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } );
		}
	};

	this.getTimewarp = function() {
		if ( this._vrHMD && this._vrHMD.getTimewarp ) {
			this._vrHMD.getTimewarp();
		}
	};

	this.setTimewarp = function( val ) {
		if ( this._vrHMD && this._vrHMD.setTimewarp ) {
			this._vrHMD.setTimewarp( val );
		}
	};

	this.FovToNDCScaleOffset = function( fov ) {
		var pxscale = 2.0 / (fov.leftTan + fov.rightTan);
		var pxoffset = (fov.leftTan - fov.rightTan) * pxscale * 0.5;
		var pyscale = 2.0 / (fov.upTan + fov.downTan);
		var pyoffset = (fov.upTan - fov.downTan) * pyscale * 0.5;
		return { scale: [pxscale, pyscale], offset: [pxoffset, pyoffset] };
	};

	this.FovPortToProjection = function( fov, rightHanded /* = true */, zNear /* = 0.01 */, zFar /* = 10000.0 */ )
	{
		rightHanded = rightHanded === undefined ? true : rightHanded;
		zNear = zNear === undefined ? 0.01 : zNear;
		zFar = zFar === undefined ? 10000.0 : zFar;

		var handednessScale = rightHanded ? -1.0 : 1.0;

		// start with an identity matrix
		var mobj = new THREE.Matrix4();
		var m = mobj.elements;

		// and with scale/offset info for normalized device coords
		var scaleAndOffset = this.FovToNDCScaleOffset(fov);

		// X result, map clip edges to [-w,+w]
		m[0*4+0] = scaleAndOffset.scale[0];
		m[0*4+1] = 0.0;
		m[0*4+2] = scaleAndOffset.offset[0] * handednessScale;
		m[0*4+3] = 0.0;

		// Y result, map clip edges to [-w,+w]
		// Y offset is negated because this proj matrix transforms from world coords with Y=up,
		// but the NDC scaling has Y=down (thanks D3D?)
		m[1*4+0] = 0.0;
		m[1*4+1] = scaleAndOffset.scale[1];
		m[1*4+2] = -scaleAndOffset.offset[1] * handednessScale;
		m[1*4+3] = 0.0;

		// Z result (up to the app)
		m[2*4+0] = 0.0;
		m[2*4+1] = 0.0;
		m[2*4+2] = zFar / (zNear - zFar) * -handednessScale;
		m[2*4+3] = (zFar * zNear) / (zNear - zFar);

		// W result (= Z in)
		m[3*4+0] = 0.0;
		m[3*4+1] = 0.0;
		m[3*4+2] = handednessScale;
		m[3*4+3] = 0.0;

		mobj.transpose();

		return mobj;
	};

	this.FovToProjection = function( fov, rightHanded /* = true */, zNear /* = 0.01 */, zFar /* = 10000.0 */ )
	{
		var DEG2RAD = Math.PI / 180.0;

		var fovPort = {
			upTan: Math.tan(fov.upDegrees * DEG2RAD),
			downTan: Math.tan(fov.downDegrees * DEG2RAD),
			leftTan: Math.tan(fov.leftDegrees * DEG2RAD),
			rightTan: Math.tan(fov.rightDegrees * DEG2RAD)
		};
		return this.FovPortToProjection(fovPort, rightHanded, zNear, zFar);
	};

};<|endoftext|>


<commit_before>define(function (require) {
    var activity = require("sugar-web/activity/activity");
    var ROT = require("rot");

    require(['domReady!'], function (doc) {
        activity.setup();

        var canvasWidth;
        var canvasHeight;
        var mazeWidth = 30;
        var mazeHeight = 20;

        var wallColor = "#101010";
        var corridorColor = "#ffffff";

        var cellWidth;
        var cellHeight;

        var mazeWalls = [];
        var mazeDirections = [];
        var mazeForks = [];

        var dirOrders = ['north', 'east', 'south', 'west'];

        var directions = {};
        dirOrders.forEach(function (dir, i) {
            directions[dir] = i;
        });

        var controls = {
            'arrows': [38, 39, 40, 37],
            'wasd': [87, 68, 83, 65],
            'ijkl': [73, 76, 75, 74]
        };

        var players = {};

        var debug = true;

        var mazeCanvas = document.getElementById("maze");
        var ctx = mazeCanvas.getContext("2d");

        var updateMazeSize = function () {
            var toolbarElem = document.getElementById("main-toolbar");

            canvasWidth = window.innerWidth;
            canvasHeight = window.innerHeight - toolbarElem.offsetHeight - 1;

            cellWidth = Math.ceil(canvasWidth / mazeWidth);
            cellHeight = Math.ceil(canvasHeight / mazeHeight);

            mazeCanvas.width = canvasWidth;
            mazeCanvas.height = canvasHeight;
        };
        updateMazeSize();

        var onWindowResize = function () {
            updateMazeSize();
            drawMaze();
        };
        window.addEventListener('resize', onWindowResize);

        var countOptions = function (x, y) {
            var dirs = mazeDirections[x][y];
            return dirs.reduce(function (previousValue, currentValue) {
                return previousValue + currentValue;
            });
        };

        var getDirections = function (x, y) {
            var dirs = [0, 0, 0, 0];

            if (mazeWalls[x][y] == 1) {
                return dirs;
            }

            if (mazeWalls[x-1][y] == 0) {
                dirs[directions.west] = 1;
            }
            if (mazeWalls[x+1][y] == 0) {
                dirs[directions.east] = 1;
            }
            if (mazeWalls[x][y-1] == 0) {
                dirs[directions.north] = 1;
            }
            if (mazeWalls[x][y+1] == 0) {
                dirs[directions.south] = 1;
            }

            return dirs;
        };

        var findDirections = function () {
            mazeDirections = [];
            for (var x=0; x<mazeWidth; x++) {
                mazeDirections[x] = new Array(mazeHeight);
            }
            for (var x=0; x<mazeWidth; x++) {
                for (var y=0; y<mazeHeight; y++) {
                    mazeDirections[x][y] = getDirections(x, y);
                }
            }
        };

        var isDeadEnd = function (x, y) {
            return countOptions(x, y) == 1;
        };

        var isFork = function (x, y) {
            return countOptions(x, y) > 2;
        };

        var findForks = function () {
            mazeForks = [];
            for (var x=0; x<mazeWidth; x++) {
                mazeForks[x] = new Array(mazeHeight);
            }
            for (var x=0; x<mazeWidth; x++) {
                for (var y=0; y<mazeHeight; y++) {
                    if (isDeadEnd(x, y) || isFork(x, y)) {
                        mazeForks[x][y] = 1;
                    }
                }
            }
        };

        var onCellGenerated = function (x, y, value) {
            mazeWalls[x][y] = value;
        };

        var generateMaze = function () {
            mazeWalls = [];
            for (var x=0; x<mazeWidth; x++) {
                mazeWalls[x] = new Array(mazeHeight);
            }
            var maze = new ROT.Map.IceyMaze(mazeWidth, mazeHeight, 1);
            //var maze = new ROT.Map.EllerMaze(mazeWidth, mazeHeight, 1);
            maze.create(onCellGenerated);

            findDirections();
            findForks();
        };
        generateMaze();

        var drawCell = function (x, y, value) {
            if (value == 1) {
                ctx.fillStyle = wallColor;
            } else {
                ctx.fillStyle = corridorColor;
            }
            ctx.fillRect(cellWidth * x, cellHeight * y, cellWidth, cellHeight);
        };

        var drawPoint = function (x, y, color, size) {
            if (size === undefined) {
                size = 0.5;
            }

            var centerX = cellWidth * (x + 0.5);
            var centerY = cellHeight * (y + 0.5);
            var radius = size * cellWidth / 2;

            ctx.beginPath();
            ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
            ctx.fillStyle = color;
            ctx.fill();
        };

        var drawMaze = function () {
            for (var x=0; x<mazeWidth; x++) {
                for (var y=0; y<mazeHeight; y++) {
                    drawCell(x, y, mazeWalls[x][y]);
                }
            }

            if (debug) {
                for (var x=0; x<mazeWidth; x++) {
                    for (var y=0; y<mazeHeight; y++) {
                        if (mazeForks[x][y] == 1) {
                            drawPoint(x, y, '#faa');
                        }
                    }
                }
            }

            drawPoint(mazeWidth-3, mazeHeight-3, '#afa');

            for (control in players) {
                var player = players[control];
                drawPoint(player.x, player.y, player.color, 1);
            };

        };

        drawMaze();

        var Player = function () {
            this.x = 1;
            this.y = 1;
            this.color = '#'+Math.floor(Math.random()*16777215).toString(16);
        };

        Player.prototype.canGo = function (direction) {
            var dirs = mazeDirections[this.x][this.y];
            var i = directions[direction];
            return dirs[i] == 1;
        };

        Player.prototype.move = function (direction) {
            if (!(this.canGo(direction))) {
                return;
            }
            if (direction == 'north') {
                this.y -= 1;
            }
            if (direction == 'east') {
                this.x += 1;
            }
            if (direction == 'south') {
                this.y += 1;
            }
            if (direction == 'west') {
                this.x -= 1;
            }
        };

        var onKeyDown = function (event) {
            var currentControl;
            var currentDirection;
            for (control in controls) {
                if (controls[control].indexOf(event.keyCode) != -1) {
                    currentControl = control;
                    currentDirection = dirOrders[controls[control].
                                                 indexOf(event.keyCode)];
                }
            }
            if (currentControl === undefined) {
                return;
            }

            if (!(currentControl in players)) {
                players[currentControl] = new Player();
            }
            players[currentControl].move(currentDirection);
            drawMaze();
        };

        document.addEventListener("keydown", onKeyDown);

    });

});
<commit_msg>Only redraw the changed areas<commit_after>define(function (require) {
    var activity = require("sugar-web/activity/activity");
    var ROT = require("rot");

    require(['domReady!'], function (doc) {
        activity.setup();

        var canvasWidth;
        var canvasHeight;
        var mazeWidth = 30;
        var mazeHeight = 20;

        var wallColor = "#101010";
        var corridorColor = "#ffffff";

        var cellWidth;
        var cellHeight;

        var mazeWalls = [];
        var mazeDirections = [];
        var mazeForks = [];

        var dirOrders = ['north', 'east', 'south', 'west'];

        var directions = {};
        dirOrders.forEach(function (dir, i) {
            directions[dir] = i;
        });

        var controls = {
            'arrows': [38, 39, 40, 37],
            'wasd': [87, 68, 83, 65],
            'ijkl': [73, 76, 75, 74]
        };

        var players = {};

        var debug = true;

        var mazeCanvas = document.getElementById("maze");
        var ctx = mazeCanvas.getContext("2d");

        var updateMazeSize = function () {
            var toolbarElem = document.getElementById("main-toolbar");

            canvasWidth = window.innerWidth;
            canvasHeight = window.innerHeight - toolbarElem.offsetHeight - 1;

            cellWidth = Math.ceil(canvasWidth / mazeWidth);
            cellHeight = Math.ceil(canvasHeight / mazeHeight);

            mazeCanvas.width = canvasWidth;
            mazeCanvas.height = canvasHeight;
        };
        updateMazeSize();

        var onWindowResize = function () {
            updateMazeSize();
            drawMaze();
        };
        window.addEventListener('resize', onWindowResize);

        var countOptions = function (x, y) {
            var dirs = mazeDirections[x][y];
            return dirs.reduce(function (previousValue, currentValue) {
                return previousValue + currentValue;
            });
        };

        var getDirections = function (x, y) {
            var dirs = [0, 0, 0, 0];

            if (mazeWalls[x][y] == 1) {
                return dirs;
            }

            if (mazeWalls[x-1][y] == 0) {
                dirs[directions.west] = 1;
            }
            if (mazeWalls[x+1][y] == 0) {
                dirs[directions.east] = 1;
            }
            if (mazeWalls[x][y-1] == 0) {
                dirs[directions.north] = 1;
            }
            if (mazeWalls[x][y+1] == 0) {
                dirs[directions.south] = 1;
            }

            return dirs;
        };

        var findDirections = function () {
            mazeDirections = [];
            for (var x=0; x<mazeWidth; x++) {
                mazeDirections[x] = new Array(mazeHeight);
            }
            for (var x=0; x<mazeWidth; x++) {
                for (var y=0; y<mazeHeight; y++) {
                    mazeDirections[x][y] = getDirections(x, y);
                }
            }
        };

        var isDeadEnd = function (x, y) {
            return countOptions(x, y) == 1;
        };

        var isFork = function (x, y) {
            return countOptions(x, y) > 2;
        };

        var findForks = function () {
            mazeForks = [];
            for (var x=0; x<mazeWidth; x++) {
                mazeForks[x] = new Array(mazeHeight);
            }
            for (var x=0; x<mazeWidth; x++) {
                for (var y=0; y<mazeHeight; y++) {
                    if (isDeadEnd(x, y) || isFork(x, y)) {
                        mazeForks[x][y] = 1;
                    }
                }
            }
        };

        var onCellGenerated = function (x, y, value) {
            mazeWalls[x][y] = value;
        };

        var generateMaze = function () {
            mazeWalls = [];
            for (var x=0; x<mazeWidth; x++) {
                mazeWalls[x] = new Array(mazeHeight);
            }
            var maze = new ROT.Map.IceyMaze(mazeWidth, mazeHeight, 1);
            //var maze = new ROT.Map.EllerMaze(mazeWidth, mazeHeight, 1);
            maze.create(onCellGenerated);

            findDirections();
            findForks();
        };
        generateMaze();

        var drawGround = function (x, y, value) {
            if (value == 1) {
                ctx.fillStyle = wallColor;
            } else {
                ctx.fillStyle = corridorColor;
            }
            ctx.fillRect(cellWidth * x, cellHeight * y, cellWidth, cellHeight);
        };

        var drawPoint = function (x, y, color, size) {
            if (size === undefined) {
                size = 0.5;
            }

            var centerX = cellWidth * (x + 0.5);
            var centerY = cellHeight * (y + 0.5);
            var radius = size * cellWidth / 2;

            ctx.beginPath();
            ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
            ctx.fillStyle = color;
            ctx.fill();
        };

        var drawMazeCell = function (x, y) {
            drawGround(x, y, mazeWalls[x][y]);

            if (debug) {
                if (mazeForks[x][y] == 1) {
                    drawPoint(x, y, '#faa');
                }
            }

            if (x == mazeWidth-3 && y == mazeHeight-3) {
                drawPoint(mazeWidth-3, mazeHeight-3, '#afa');
            }

            for (control in players) {
                var player = players[control];
                if (x == player.x && y == player.y) {
                    drawPoint(player.x, player.y, player.color, 1);
                }
            };

        }

        var drawMaze = function () {
            for (var x=0; x<mazeWidth; x++) {
                for (var y=0; y<mazeHeight; y++) {
                    drawGround(x, y, mazeWalls[x][y]);
                }
            }

            if (debug) {
                for (var x=0; x<mazeWidth; x++) {
                    for (var y=0; y<mazeHeight; y++) {
                        if (mazeForks[x][y] == 1) {
                            drawPoint(x, y, '#faa');
                        }
                    }
                }
            }

            drawPoint(mazeWidth-3, mazeHeight-3, '#afa');

            for (control in players) {
                var player = players[control];
                drawPoint(player.x, player.y, player.color, 1);
            };

        };

        drawMaze();

        var Player = function () {
            this.x = 1;
            this.y = 1;
            this.color = '#'+Math.floor(Math.random()*16777215).toString(16);
        };

        Player.prototype.canGo = function (direction) {
            var dirs = mazeDirections[this.x][this.y];
            var i = directions[direction];
            return dirs[i] == 1;
        };

        Player.prototype.move = function (direction) {
            if (!(this.canGo(direction))) {
                return;
            }
            if (direction == 'north') {
                this.y -= 1;
            }
            if (direction == 'east') {
                this.x += 1;
            }
            if (direction == 'south') {
                this.y += 1;
            }
            if (direction == 'west') {
                this.x -= 1;
            }
        };

        var onKeyDown = function (event) {
            var currentControl;
            var currentDirection;
            for (control in controls) {
                if (controls[control].indexOf(event.keyCode) != -1) {
                    currentControl = control;
                    currentDirection = dirOrders[controls[control].
                                                 indexOf(event.keyCode)];
                }
            }
            if (currentControl === undefined) {
                return;
            }

            if (!(currentControl in players)) {
                players[currentControl] = new Player();
            }

            var player = players[currentControl];
            var oldX = player.x;
            var oldY = player.y;
            player.move(currentDirection);
            drawMazeCell(oldX, oldY);
            drawMazeCell(player.x, player.y);
        };

        document.addEventListener("keydown", onKeyDown);

    });

});
<|endoftext|>


<commit_before>define(function (require) {
    var Vector = require('./Vector');
    var Settings = require('./Settings');
    var Sprite = require('./Sprite');
    var Layer = require('./Layer');
    var previousTimeStamp = null;

    var layers = [];
    for(var i = 0; i < Settings.numberOfLayers; i++) {
        layers.push(Layer(document.body, Settings.canvasSize, Settings.canvasScale));
    }

    /*
    initialize and attach stuff here
    */

    var jelly = Sprite("img/Jelly.png", Vector(200, 0));
    layers[0].attachSprite(jelly);

    var jelly2 = Sprite("img/Jelly.png", Vector(210, 10));
    layers[1].attachSprite(jelly2);

    var loop = function (timeStamp) {
        if(!previousTimeStamp) previousTimeStamp = timeStamp;
        var elapsedTimeSeconds = (timeStamp - previousTimeStamp) / 1000.0;

        /*
        update position code here, every frame
        */

        for(var i = 0; i < layers.length; i++) {
            layers[i].draw(elapsedTimeSeconds);
        }
        window.requestAnimationFrame(loop);
    };
    window.requestAnimationFrame(loop);

    console.log("Loaded.");
});
<commit_msg>Animation working.<commit_after>define(function (require) {
    var Vector = require('./Vector');
    var Settings = require('./Settings');
    var Sprite = require('./Sprite');
    var Layer = require('./Layer');
    var previousTimeStamp = null;

    var layers = [];
    for(var i = 0; i < Settings.numberOfLayers; i++) {
        layers.push(Layer(document.body, Settings.canvasSize, Settings.canvasScale));
    }

    /*
    initialize and attach stuff here
    */

    var jelly = Sprite("img/Jelly.png", Vector(200, 0));
    layers[0].attachSprite(jelly);

    var jelly2 = Sprite("img/Jelly.png", Vector(210, 10));
    layers[1].attachSprite(jelly2);

    var loop = function (timeStamp) {
        if(!previousTimeStamp) previousTimeStamp = timeStamp;
        var elapsedTimeSeconds = (timeStamp - previousTimeStamp) / 1000.0;

        /*
        update position code here, every frame
        */
        jelly2.position.x -= 10 * elapsedTimeSeconds;

        for(var i = 0; i < layers.length; i++) {
            layers[i].draw(elapsedTimeSeconds);
        }
        previousTimeStamp = timeStamp;
        window.requestAnimationFrame(loop);
    };
    window.requestAnimationFrame(loop);

    console.log("Loaded.");
});
<|endoftext|>


<commit_before>var debug = false;
var trace = false;

var text = [];
var delay = 50;
var currentWord = 0;
var currentChar = 0;
var dest = null;

console.log("testing - 2");
document.title = "Spencer's Portfolio";
$('meta[name=description]').remove();
$('head').append('<meta name="description" content="something about me">');

function type() {
    if(debug && trace) console.log("type()");
    dest.innerHTML = text[currentWord].substr(0, ++currentChar);
    if (currentChar > text[currentWord].length) setTimeout("unType()", 1500);
    else                                        setTimeout("type()", delay);
}

function unType() {
    if (debug && trace) console.log("unType()");

    dest.innerHTML = text[currentWord].substr(0, currentChar);
    if (--currentChar === 0) {
        dest.innerHTML = "
"; // otherwise page will jump due to line deletion
        if (currentWord + 1 === text.length) currentWord = 0;
        else ++currentWord;
        setTimeout("type()", 750);
    } else {
        setTimeout("unType()", delay/2);
    }
}

function startTyping(textParam, delayParam, destinationParam) {
    if (debug && trace) console.log("startTyping()");

    text = textParam;
    delay = delayParam;
    dest = document.getElementById(destinationParam);
    setTimeout("type()", 500);
}

window.onload = startTyping(["Software Developer", "University of Texas Student", "Entrepreneur"], 50, "messages");<commit_msg>updated description<commit_after>var debug = false;
var trace = false;

var text = [];
var delay = 50;
var currentWord = 0;
var currentChar = 0;
var dest = null;

console.log("testing - 2");
document.title = "Spencer's Portfolio";
$('meta[name=description]').remove();
$('head').append('<meta name="description" content="A portolio about Spencer Shadley regarding projects, resume, etc.">');

function type() {
    if(debug && trace) console.log("type()");
    dest.innerHTML = text[currentWord].substr(0, ++currentChar);
    if (currentChar > text[currentWord].length) setTimeout("unType()", 1500);
    else                                        setTimeout("type()", delay);
}

function unType() {
    if (debug && trace) console.log("unType()");

    dest.innerHTML = text[currentWord].substr(0, currentChar);
    if (--currentChar === 0) {
        dest.innerHTML = "
"; // otherwise page will jump due to line deletion
        if (currentWord + 1 === text.length) currentWord = 0;
        else ++currentWord;
        setTimeout("type()", 750);
    } else {
        setTimeout("unType()", delay/2);
    }
}

function startTyping(textParam, delayParam, destinationParam) {
    if (debug && trace) console.log("startTyping()");

    text = textParam;
    delay = delayParam;
    dest = document.getElementById(destinationParam);
    setTimeout("type()", 500);
}

window.onload = startTyping(["Software Developer", "University of Texas Student", "Entrepreneur"], 50, "messages");<|endoftext|>


<commit_before>var ball;
var ballRadius = 1.5;
var ballSpeed = 1;
var ballColor = 0x00ffff;
var ballDirection;
var prevBallPosition = new THREE.Vector3(0, 0, 0);

var MAX_TRAIL_LENGTH = 50000;
var trailPos = 0;

var raycaster;

var prevIntersectionPoint;
var nextIntersectionPoint;
var nextIntersectionDirection;
var distanceToNextPoint;
var distanceTraveled;

var currSegmentTrail;
var trailHistory;

function initBall(scene) {
    // add ball geometry to the scene
    var geometry = new THREE.SphereGeometry( ballRadius, 32, 32 );
    var material = new THREE.MeshBasicMaterial( {color: ballColor} );
    ball = new THREE.Mesh( geometry, material );
    scene.add( ball );

    // randomize the ball direction for each run
    ballDirection = new THREE.Vector3(0, 0, 0);
    ballDirection.x = (Math.random() - 0.5) * 2.0;
    ballDirection.y = (Math.random() - 0.5) * 2.0;
    ballDirection.z = (Math.random() - 0.5) * 2.0;
    ballDirection.normalize();

    // create the ball trail, add it to the scene
    var trailHistoryMaterial = new THREE.LineBasicMaterial({ color: ballColor, transparent: true, opacity: 0.5});
    trailHistory = new THREE.Line(new THREE.Geometry(), trailHistoryMaterial, THREE.LinePieces);
    trailHistory.geometry.dynamic = true;
    trailHistory.frustumCulled = false;

    for (var i=0; i < MAX_TRAIL_LENGTH; i++){
        trailHistory.geometry.vertices.push(new THREE.Vector3(0, 0, 0));
    }

    scene.add(trailHistory);

    var currSegmentMaterial = new THREE.LineBasicMaterial({ color: ballColor });
    currSegmentTrail = new THREE.Line(new THREE.Geometry(), currSegmentMaterial);
    currSegmentTrail.dynamic = true;
    currSegmentTrail.frustumCulled = false;

    currSegmentTrail.geometry.vertices.push(new THREE.Vector3(0, 0, 0));
    currSegmentTrail.geometry.vertices.push(new THREE.Vector3(0, 0, 0));

    scene.add(currSegmentTrail);

    raycaster = new THREE.Raycaster();
}

function updateBallPosition() {
    if (!ball || !meshObject) {
        return; // if scene hasn't been initialized yet - bail
    }

    if (!nextIntersectionPoint) {
        // calculate the initial intersection of the ball and the mesh (next intersection points will be updated when the ball changes direction)
        prevIntersectionPoint = ball.position.clone();
        calcNextIntersectionPoint(ball.position, ballDirection);
    }

    prevBallPosition.x = ball.position.x;
    prevBallPosition.y = ball.position.y;
    prevBallPosition.z = ball.position.z;

    ball.position.x += ballDirection.x * ballSpeed;
    ball.position.y += ballDirection.y * ballSpeed;
    ball.position.z += ballDirection.z * ballSpeed;

    distanceTraveled += prevBallPosition.distanceTo(ball.position);
    updateCurrSegmentTrail(prevIntersectionPoint, ball.position);

    if ((distanceTraveled + ballRadius) > distanceToNextPoint) {
        addSegmentToHistoryTrail(prevIntersectionPoint, ball.position.clone());

        ballDirection = nextIntersectionDirection;

        prevIntersectionPoint = ball.position.clone();
        calcNextIntersectionPoint(ball.position, nextIntersectionDirection);
    }
}

function calcNextIntersectionPoint(origin, direction) {
    raycaster.set(origin, direction);
    var intersectionResult = raycaster.intersectObject(meshObject);

    if (intersectionResult.length > 0) {
        nextIntersectionPoint = intersectionResult[0].point;
        nextIntersectionDirection = intersectionResult[0].face.normal;

        // add some randomness to the bounce direction, to make things more interesting..
        nextIntersectionDirection.x += (Math.random() - 0.5) * 0.2;
        nextIntersectionDirection.y += (Math.random() - 0.5) * 0.2;
        nextIntersectionDirection.z += (Math.random() - 0.5) * 0.2;
        nextIntersectionDirection.normalize();

        distanceToNextPoint = origin.distanceTo(nextIntersectionPoint);
        distanceTraveled = 0.0;
    }
}

function addSegmentToHistoryTrail(startPoint, endPoint) {
    var vertices = trailHistory.geometry.vertices;

    vertices[trailPos * 2].x = startPoint.x;
    vertices[trailPos * 2].y = startPoint.y;
    vertices[trailPos * 2].z = startPoint.z;

    vertices[trailPos * 2 + 1].x = endPoint.x;
    vertices[trailPos * 2 + 1].y = endPoint.y;
    vertices[trailPos * 2 + 1].z = endPoint.z;

    trailHistory.geometry.verticesNeedUpdate = true;
    trailPos = trailPos + 1;
}

function updateCurrSegmentTrail(startPoint, endPoint) {
    var vertices = currSegmentTrail.geometry.vertices;

    vertices[0].x = startPoint.x;
    vertices[0].y = startPoint.y;
    vertices[0].z = startPoint.z;

    vertices[1].x = endPoint.x;
    vertices[1].y = endPoint.y;
    vertices[1].z = endPoint.z;

    currSegmentTrail.geometry.verticesNeedUpdate = true;
}<commit_msg>added wireframe face tracing - add lines from each face hit point to the corners of that face<commit_after>var ball;
var ballRadius = 1.5;
var ballSpeed = 1.5;
var ballColor = 0x00ffff;
var ballDirection;
var prevBallPosition = new THREE.Vector3(0, 0, 0);

var MAX_TRAIL_LENGTH = 50000;
var trailPos = 0;

var MAX_FACE_WIREFRAME_LENGTH = 150000;
var faceWireframePos = 0;

var raycaster;

var prevIntersectionPoint;
var nextIntersectionPoint;
var nextIntersectionDirection;
var nextIntersectionFace;
var distanceToNextPoint;
var distanceTraveled;

var currSegmentTrail;
var trailHistory;
var faceWireframe;

function initBall(scene) {
    // add ball geometry to the scene
    var geometry = new THREE.SphereGeometry( ballRadius, 32, 32 );
    var material = new THREE.MeshBasicMaterial( {color: ballColor} );
    ball = new THREE.Mesh( geometry, material );
    scene.add( ball );

    // randomize the ball direction for each run
    ballDirection = new THREE.Vector3(0, 0, 0);
    ballDirection.x = (Math.random() - 0.5) * 2.0;
    ballDirection.y = (Math.random() - 0.5) * 2.0;
    ballDirection.z = (Math.random() - 0.5) * 2.0;
    ballDirection.normalize();

    // create the ball trail, add it to the scene
    var trailHistoryMaterial = new THREE.LineBasicMaterial({ color: ballColor, transparent: true, opacity: 0.5});
    trailHistory = new THREE.Line(new THREE.Geometry(), trailHistoryMaterial, THREE.LinePieces);
    trailHistory.geometry.dynamic = true;
    trailHistory.frustumCulled = false;

    for (var i=0; i < MAX_TRAIL_LENGTH; i++){
        trailHistory.geometry.vertices.push(new THREE.Vector3(0, 0, 0));
    }

    scene.add(trailHistory);

    var currSegmentMaterial = new THREE.LineBasicMaterial({ color: ballColor });
    currSegmentTrail = new THREE.Line(new THREE.Geometry(), currSegmentMaterial);
    currSegmentTrail.dynamic = true;
    currSegmentTrail.frustumCulled = false;

    currSegmentTrail.geometry.vertices.push(new THREE.Vector3(0, 0, 0));
    currSegmentTrail.geometry.vertices.push(new THREE.Vector3(0, 0, 0));

    scene.add(currSegmentTrail);

    // create face wireframe line additions, and add it to the scene
    var wireframeMaterial = new THREE.LineBasicMaterial({ color: 0xff00ff, transparent: true, opacity: 0.5});
    faceWireframe = new THREE.Line(new THREE.Geometry(), wireframeMaterial, THREE.LinePieces);
    faceWireframe.geometry.dynamic = true;
    faceWireframe.frustumCulled = false;

    for (var i=0; i < MAX_FACE_WIREFRAME_LENGTH; i++){
        faceWireframe.geometry.vertices.push(new THREE.Vector3(0, 0, 0));
    }

    scene.add(faceWireframe);

    raycaster = new THREE.Raycaster();
}

function updateBallPosition() {
    if (!ball || !meshObject) {
        return; // if scene hasn't been initialized yet - bail
    }

    if (!nextIntersectionPoint) {
        // calculate the initial intersection of the ball and the mesh (next intersection points will be updated when the ball changes direction)
        prevIntersectionPoint = ball.position.clone();
        calcNextIntersectionPoint(ball.position, ballDirection);
    }

    prevBallPosition.x = ball.position.x;
    prevBallPosition.y = ball.position.y;
    prevBallPosition.z = ball.position.z;

    ball.position.x += ballDirection.x * ballSpeed;
    ball.position.y += ballDirection.y * ballSpeed;
    ball.position.z += ballDirection.z * ballSpeed;

    distanceTraveled += prevBallPosition.distanceTo(ball.position);
    updateCurrSegmentTrail(prevIntersectionPoint, ball.position);

    if ((distanceTraveled + ballRadius) > distanceToNextPoint) {
        addSegmentToHistoryTrail(prevIntersectionPoint, ball.position.clone());
        addWireframePoint(ball.position.clone(), nextIntersectionFace);

        ballDirection = nextIntersectionDirection;

        prevIntersectionPoint = ball.position.clone();
        calcNextIntersectionPoint(ball.position, nextIntersectionDirection);
    }
}

function calcNextIntersectionPoint(origin, direction) {
    raycaster.set(origin, direction);
    var intersectionResult = raycaster.intersectObject(meshObject);

    if (intersectionResult.length > 0) {
        nextIntersectionPoint = intersectionResult[0].point;
        nextIntersectionDirection = intersectionResult[0].face.normal;
        nextIntersectionFace = intersectionResult[0].face;

        // add some randomness to the bounce direction, to make things more interesting..
        nextIntersectionDirection.x += (Math.random() - 0.5) * 0.8;
        nextIntersectionDirection.y += (Math.random() - 0.5) * 0.8;
        nextIntersectionDirection.z += (Math.random() - 0.5) * 0.8;
        nextIntersectionDirection.normalize();

        distanceToNextPoint = origin.distanceTo(nextIntersectionPoint);
        distanceTraveled = 0.0;
    }
}

function addSegmentToHistoryTrail(startPoint, endPoint) {
    var vertices = trailHistory.geometry.vertices;

    vertices[trailPos * 2].x = startPoint.x;
    vertices[trailPos * 2].y = startPoint.y;
    vertices[trailPos * 2].z = startPoint.z;

    vertices[trailPos * 2 + 1].x = endPoint.x;
    vertices[trailPos * 2 + 1].y = endPoint.y;
    vertices[trailPos * 2 + 1].z = endPoint.z;

    trailHistory.geometry.verticesNeedUpdate = true;
    trailPos = trailPos + 1;
}

function updateCurrSegmentTrail(startPoint, endPoint) {
    var vertices = currSegmentTrail.geometry.vertices;

    vertices[0].x = startPoint.x;
    vertices[0].y = startPoint.y;
    vertices[0].z = startPoint.z;

    vertices[1].x = endPoint.x;
    vertices[1].y = endPoint.y;
    vertices[1].z = endPoint.z;

    currSegmentTrail.geometry.verticesNeedUpdate = true;
}

function addWireframePoint(hitPoint, face) {
    var meshVertices = meshObject.geometry.attributes.position.array;

    var vertices = faceWireframe.geometry.vertices;

    // first line
    vertices[faceWireframePos * 6].x = meshVertices[face.a * 3];
    vertices[faceWireframePos * 6].y = meshVertices[face.a * 3 + 1];
    vertices[faceWireframePos * 6].z = meshVertices[face.a * 3 + 2];

    vertices[faceWireframePos * 6 + 1].x = hitPoint.x;
    vertices[faceWireframePos * 6 + 1].y = hitPoint.y;
    vertices[faceWireframePos * 6 + 1].z = hitPoint.z;

    // second line
    vertices[faceWireframePos * 6 + 2].x = meshVertices[face.b * 3];
    vertices[faceWireframePos * 6 + 2].y = meshVertices[face.b * 3 + 1];
    vertices[faceWireframePos * 6 + 2].z = meshVertices[face.b * 3 + 2];

    vertices[faceWireframePos * 6 + 3].x = hitPoint.x;
    vertices[faceWireframePos * 6 + 3].y = hitPoint.y;
    vertices[faceWireframePos * 6 + 3].z = hitPoint.z;

    // third line
    vertices[faceWireframePos * 6 + 4].x = meshVertices[face.c * 3];
    vertices[faceWireframePos * 6 + 4].y = meshVertices[face.c * 3 + 1];
    vertices[faceWireframePos * 6 + 4].z = meshVertices[face.c * 3 + 2];

    vertices[faceWireframePos * 6 + 5].x = hitPoint.x;
    vertices[faceWireframePos * 6 + 5].y = hitPoint.y;
    vertices[faceWireframePos * 6 + 5].z = hitPoint.z;

    faceWireframe.geometry.verticesNeedUpdate = true;
    faceWireframePos = faceWireframePos + 1;
}
<|endoftext|>


<commit_before>$.getScript("./js/fullcalendar/dist/fullcalendar.min.js",function(){

  var date = new Date();
  var d = date.getDate();
  var m = date.getMonth();
  var y = date.getFullYear();

  $(document).ready(function() {

    $('#calendar').fullCalendar({
      header: {
        left: 'prevYear, prev,next, nextYear',
        center: 'title',
        right: 'agendaWeek,month,listYear'
      },
      defaultView: 'listYear',
      defaultDate: '2016-10-01',
      navLinks: true, // can click day/week names to navigate views
      weekNumberCalculation: 'ISO', // firstDay = monday
      editable: true,
      events: [
        {
          id: 999,
          title: "#1 Workshop: Intro into HTML/CSS @asquera GmbH, Ohlauer Str. 43, 10999 Berlin - http://www.asquera.de",
          start: new Date(2016, 8, 7, 19, 00, 00),
          end: new Date(2016, 8, 7, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#2 Let's tutorial HTML/CSS for Beginners! @Altes Finanzamt, Schönstedtstr. 7, 12043 Berlin - http://altesfinanzamt.blogspot.de",
          start: new Date(2016, 8, 21, 19, 00, 00),
          end: new Date(2016, 8, 21, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#3 Let's tutorial HTML/CSS for Beginners! @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 9, 13, 19, 30, 00),
          end: new Date(2016, 9, 13, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#4 Let's tutorial HTML/CSS for Beginners! @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 9, 27, 19, 30, 00),
          end: new Date(2016, 9, 27, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#5 Let's tutorial HTML/CSS for Beginners! @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 10, 10, 19, 30, 00),
          end: new Date(2016, 10, 10, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#6 Let's tutorial HTML/CSS for Beginners! @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 10, 24, 19, 30, 00),
          end: new Date(2016, 10, 24, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#7 Let's tutorial HTML/CSS for Beginners! @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 11, 8, 19, 30, 00),
          end: new Date(2016, 11, 8, 22, 00, 00),
          allDay: false
        }
      ]
    });
  });
});
<commit_msg>Change event series title<commit_after>$.getScript("./js/fullcalendar/dist/fullcalendar.min.js",function(){

  var date = new Date();
  var d = date.getDate();
  var m = date.getMonth();
  var y = date.getFullYear();

  $(document).ready(function() {

    $('#calendar').fullCalendar({
      header: {
        left: 'prevYear, prev,next, nextYear',
        center: 'title',
        right: 'agendaWeek,month,listYear'
      },
      defaultView: 'listYear',
      defaultDate: '2016-10-01',
      navLinks: true, // can click day/week names to navigate views
      weekNumberCalculation: 'ISO', // firstDay = monday
      editable: true,
      events: [
        {
          id: 999,
          title: "#1 Workshop: Intro into HTML/CSS  | @asquera GmbH, Ohlauer Str. 43, 10999 Berlin - http://www.asquera.de",
          start: new Date(2016, 8, 7, 19, 00, 00),
          end: new Date(2016, 8, 7, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#2 Let's tutorial together! (HTML/CSS for Beginners) | @Altes Finanzamt, Schönstedtstr. 7, 12043 Berlin - http://altesfinanzamt.blogspot.de",
          start: new Date(2016, 8, 21, 19, 00, 00),
          end: new Date(2016, 8, 21, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#3 Let's tutorial together! (HTML/CSS for Beginners) | @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 9, 13, 19, 30, 00),
          end: new Date(2016, 9, 13, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#4 Let's tutorial together! (HTML/CSS for Beginners) | @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 9, 27, 19, 30, 00),
          end: new Date(2016, 9, 27, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#5 Let's tutorial together! (HTML/CSS for Beginners) | @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 10, 10, 19, 30, 00),
          end: new Date(2016, 10, 10, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#6 Let's tutorial together! (HTML/CSS for Beginners) | @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 10, 24, 19, 30, 00),
          end: new Date(2016, 10, 24, 22, 00, 00),
          allDay: false
        },
        {
          id: 999,
          title: "#7 Let's tutorial together! (HTML/CSS for Beginners) | @co.up, Adalbertstr. 8, 10999 Berlin (5th floor) - http://co-up.de",
          start: new Date(2016, 11, 8, 19, 30, 00),
          end: new Date(2016, 11, 8, 22, 00, 00),
          allDay: false
        }
      ]
    });
  });
});
<|endoftext|>


<commit_before>// React view of a card
import React from "react";
require("../scss/style.scss");

let Card = React.createClass({
  render() {

    let cssClassForCard = this.props.hasFocus ? 'playing-card active-card' : 'playing-card';
    return (

        {this.props.cardInfo.name}

        {this.props.cardInfo.attack}/{this.props.cardInfo.defense}

    );

  },

  // highlight a card when clicked
  clickCard: function() {
    // card can only be highlighted and played if player has enough mana
    if (this.props.cardInfo.cost <= this.props.player.mana) {
      this.props.hasFocus = !this.props.hasFocus;
      // play card on 2nd click
      if (!this.props.hasFocus) {
        window.game.play(this.props.player.hand.indexOf(this.props.cardInfo));
      }
    }
    this.forceUpdate();
  },

});

module.exports = Card;
<commit_msg>more clear<commit_after>// React view of a card
import React from "react";
require("../scss/style.scss");

let Card = React.createClass({
  render() {

    let cssClassForCard = this.props.hasFocus ? 'playing-card active-card' : 'playing-card';
    return (

        {this.props.cardInfo.name}

        {this.props.cardInfo.attack}/{this.props.cardInfo.defense}

    );

  },

  // highlight a card when clicked
  clickCard: function() {
    // card can only be highlighted and played if player has enough mana
    if (this.props.cardInfo.cost > this.props.player.mana) {
      return;
    }
    this.props.hasFocus = !this.props.hasFocus;
    // play card on 2nd click
    if (!this.props.hasFocus) {
      window.game.play(this.props.player.hand.indexOf(this.props.cardInfo));
    }
    this.forceUpdate();
  },

});

module.exports = Card;
<|endoftext|>


<commit_before> $(document).ready(function(){

    $('#c_data').slick({
		  dots: true,
		  infinite: false,
		  speed: 300,
		  slidesToShow: 4,
		  slidesToScroll: 4,
		  responsive: [
		    {
		      breakpoint: 1024,
		      settings: {
		        slidesToShow: 3,
		        slidesToScroll: 3,
		        infinite: true,
		        dots: true
		      }
		    },
		    {
		      breakpoint: 600,
		      settings: {
		        slidesToShow: 2,
		        slidesToScroll: 2,
		      }
		    },
		    {
		      breakpoint: 500,
		      settings: {
		        slidesToShow: 1,
		        slidesToScroll: 1,
		        dots: false

		      }
		    }
		  ]
});

});<commit_msg>Fixed some whitespacing issues in carousel.js.<commit_after> $(document).ready(function(){
    $('#c_data').slick({
		  dots: true,
		  infinite: false,
		  speed: 300,
		  slidesToShow: 4,
		  slidesToScroll: 4,
		  responsive: [
		    {
		      breakpoint: 1024,
		      settings: {
		        slidesToShow: 3,
		        slidesToScroll: 3,
		        infinite: true,
		        dots: true
		      }
		    },
		    {
		      breakpoint: 600,
		      settings: {
		        slidesToShow: 2,
		        slidesToScroll: 2,
		      }
		    },
		    {
		      breakpoint: 500,
		      settings: {
		        slidesToShow: 1,
		        slidesToScroll: 1,
		        dots: false

		      }
		    }
		  ]
	});
});
<|endoftext|>


<commit_before>(function($) {
    "use strict"; // Start of use strict

    // jQuery for page scrolling feature - requires jQuery Easing plugin
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    // Highlight the top nav as scrolling occurs
    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    });

    // Closes the Responsive Menu on Menu Item Click
    $('.navbar-collapse ul li a').click(function() {
        $('.navbar-toggle:visible').click();
    });

    // Offset for Main Navigation
    $('#mainNav').affix({
        offset: {
            top: 100
        }
    })

    // Initialize and Configure Scroll Reveal Animation
    window.sr = ScrollReveal();
    sr.reveal('.sr-icons', {
        duration: 600,
        scale: 0.3,
        distance: '0px'
    }, 200);
    sr.reveal('.sr-button', {
        duration: 1000,
        delay: 200
    });
    sr.reveal('.sr-contact', {
        duration: 600,
        scale: 0.3,
        distance: '0px'
    }, 300);

    // Initialize and Configure Magnific Popup Lightbox Plugin
    $('.popup-gallery').magnificPopup({
        delegate: 'a',
        type: 'image',
        tLoading: 'Loading image #%curr%...',
        mainClass: 'mfp-img-mobile',
        gallery: {
            enabled: true,
            navigateByImgClick: true,
            preload: [0, 1] // Will preload 0 - before current, and 1 after the current image
        },
        image: {
            tError: 'The image #%curr% could not be loaded.'
        }
    });

    // Change carousel interval on testimonial section
    $('#myCarousel').carousel({
        interval: 12000
    });

    /*
    * Service form functionality
    */

    // Test for placeholder support
    $.support.placeholder = (function() {
        var i = document.createElement('input');
        return 'placeholder' in i;
    })();

    // Hide labels by default if placeholders are supported
    if($.support.placeholder) {
        $('.form-label').each(function() {
            $(this).addClass('js-hide-label');
        });

        // Code for adding/removing classes here
        $('.form-group').find('input, textarea').on('keyup blur focus', function(e) {

            // Cache our selectors
            var $this = $(this),
                $parent = $(this).parent().find("label");

            if(e.type == 'keyup') {
                if($this.val() == '') {
                    $parent.addClass('js-hide-label');
                } else {
                    $parent.removeClass('js-hide-label');
                }
            }
            else if(e.type == 'blur') {
                if($this.val() == '') {
                    $parent.addClass('js-hide-label');
                } else {
                    $parent.removeClass('js-hide-label').addClass('js-unhighlight-label');
                }
            }
            else if(e.type == 'focus') {
                if($this.val() !== '') {
                    $parent.removeClass('js-unhighlight-label');
                }
            }
        });
    }

    // To show and hide form elements
    $('.hidden-form-element').hide();

    function showRestOfForm() {
        $('.hidden-form-element').fadeIn(1500);
        $('#agree').fadeIn(1500);
    }

    $('#firstName').focus(showRestOfForm);
    $('#lastName').focus(showRestOfForm);

})(jQuery); // End of use strict
<commit_msg>Changed timer to 16 seconds on testimonial modal cycle<commit_after>(function($) {
    "use strict"; // Start of use strict

    // jQuery for page scrolling feature - requires jQuery Easing plugin
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: ($($anchor.attr('href')).offset().top - 50)
        }, 1250, 'easeInOutExpo');
        event.preventDefault();
    });

    // Highlight the top nav as scrolling occurs
    $('body').scrollspy({
        target: '.navbar-fixed-top',
        offset: 51
    });

    // Closes the Responsive Menu on Menu Item Click
    $('.navbar-collapse ul li a').click(function() {
        $('.navbar-toggle:visible').click();
    });

    // Offset for Main Navigation
    $('#mainNav').affix({
        offset: {
            top: 100
        }
    })

    // Initialize and Configure Scroll Reveal Animation
    window.sr = ScrollReveal();
    sr.reveal('.sr-icons', {
        duration: 600,
        scale: 0.3,
        distance: '0px'
    }, 200);
    sr.reveal('.sr-button', {
        duration: 1000,
        delay: 200
    });
    sr.reveal('.sr-contact', {
        duration: 600,
        scale: 0.3,
        distance: '0px'
    }, 300);

    // Initialize and Configure Magnific Popup Lightbox Plugin
    $('.popup-gallery').magnificPopup({
        delegate: 'a',
        type: 'image',
        tLoading: 'Loading image #%curr%...',
        mainClass: 'mfp-img-mobile',
        gallery: {
            enabled: true,
            navigateByImgClick: true,
            preload: [0, 1] // Will preload 0 - before current, and 1 after the current image
        },
        image: {
            tError: 'The image #%curr% could not be loaded.'
        }
    });

    // Change carousel interval on testimonial section
    $('#myCarousel').carousel({
        interval: 16000
    });

    /*
    * Service form functionality
    */

    // Test for placeholder support
    $.support.placeholder = (function() {
        var i = document.createElement('input');
        return 'placeholder' in i;
    })();

    // Hide labels by default if placeholders are supported
    if($.support.placeholder) {
        $('.form-label').each(function() {
            $(this).addClass('js-hide-label');
        });

        // Code for adding/removing classes here
        $('.form-group').find('input, textarea').on('keyup blur focus', function(e) {

            // Cache our selectors
            var $this = $(this),
                $parent = $(this).parent().find("label");

            if(e.type == 'keyup') {
                if($this.val() == '') {
                    $parent.addClass('js-hide-label');
                } else {
                    $parent.removeClass('js-hide-label');
                }
            }
            else if(e.type == 'blur') {
                if($this.val() == '') {
                    $parent.addClass('js-hide-label');
                } else {
                    $parent.removeClass('js-hide-label').addClass('js-unhighlight-label');
                }
            }
            else if(e.type == 'focus') {
                if($this.val() !== '') {
                    $parent.removeClass('js-unhighlight-label');
                }
            }
        });
    }

    // To show and hide form elements
    $('.hidden-form-element').hide();

    function showRestOfForm() {
        $('.hidden-form-element').fadeIn(1500);
        $('#agree').fadeIn(1500);
    }

    $('#firstName').focus(showRestOfForm);
    $('#lastName').focus(showRestOfForm);

})(jQuery); // End of use strict
<|endoftext|>


<commit_before>//This is a chip-8 emulator
//Written by Jerry Schneider

//Load the fontset into memory at 0x50
function loadFontset(){
    for( i = 0; i < chip8_fontset.length; i++){
        memoryView[0x50 + i] = chip8_fontset[i];
    }
};

//Hardcoded fontset for the chip8
var chip8_fontset = [
  0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
  0x20, 0x60, 0x20, 0x20, 0x70, // 1
  0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
  0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
  0x90, 0x90, 0xF0, 0x10, 0x10, // 4
  0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
  0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
  0xF0, 0x10, 0x20, 0x40, 0x40, // 7
  0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
  0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
  0xF0, 0x90, 0xF0, 0x90, 0x90, // A
  0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
  0xF0, 0x80, 0x80, 0x80, 0xF0, // C
  0xE0, 0x90, 0x90, 0x90, 0xE0, // D
  0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
  0xF0, 0x80, 0xF0, 0x80, 0x80  // F
];

//Recieves messages from the font end
self.onmessage = function(event){
    //Begin emulation
    if(event.data == "start"){
        main();
    }
    //Kill the emulator
    else if(event.data == "stop"){
        self.close();
    }
};

//The current opcode
var opcode;

//4k memory
// 0x000-0x1FF - Chip 8 interpreter (contains font set in emu)
// 0x050-0x0A0 - Used for the built in 4x5 pixel font set (0-F)
// 0x200-0xFFF - Program ROM and work RAM
var memory = new ArrayBuffer(4096);

var memoryView = new Uint8Array(memory, 0);

//Registers
var V = [];

//Index register (upper 4 bits are unused)
var I = new ArrayBuffer(2);

//Program counter (upper 4 bits are unused)
var pc = new ArrayBuffer(2);

//Pixel Display 64 x 32
var pixels = [64 * 32];

//Timers which count down from X to 0 at 60hz
var delay_timer;
var sound_timer;

//16 frame stack
var stack = [16];
//Stack pointer
var sp;

//Key state
var key = [16];

function memoryInit(){
    //Init 16 8-bit registers
    for( i = 0; i < 16; i++ ){
        V.push( new ArrayBuffer(8) );
    }
    //Applications are expected to be loaded at 0x200
    pc = 0x200;

    //Clear memory
    opcode = 0;
    sp = 0;
    I = 0;

    //Load Fontset
    loadFontset();
}

function decodeAndExecute( opcode ){
    switch( opcode & 0xF000 ){

        case 0x0000:    // 0---: more decoding
            switch( opcode & 0x000F ){

                case 0x0000:    // 0x00E0: clear the screen
                break;

                case 0x000E:    // 0x00EE: return from a subroutine
                break;

                default:
                    console.log("Unknown opcode: " + opcode.toString(16));
            }
        break;

        case 0x1000:    // 1NNN: Jumps to address NNN
        break

        case 0x2000:    // 2NNN: Calls subroutine at address NNN
        break;

        case 0x3000:    // 3XNN: Skips the next instrouction if VX equals NN
        break;

        case 0x4000:    // 4XNN: Skips the next instrouction if VX does not equal NN
        break;

        case 0x5000:    // 5XY0: Skips the next instrouction if VX equals VY
        break;

        case 0x6000:    // 6XNN: Sets VX to NN
        break;

        case 0x7000:    // 7XNN: Adds NN to VX
        break;

        case 0x8000:    // 8---: more decoding
            switch( opcode & 0x000F ){
                case 0x0000:    // 8XY0: Sets VX to the value of VY
                break;

                case 0x0001:    // 8XY1: Sets VX to VX | VY
                break;

                case 0x0002:    // 8XY2: Sets VX to VX & VY
                break;

                case 0x0003:    // 8XY3: Sets VX to VX XOR VY
                break;

                case 0x0004:    // 8XY4: Adds VY to VX. VF is set to 1 when there's a carry, and to 0 when there isn't
                break;

                case 0x0005:    // 8XY5: VY is subtracted from VX. VF is set to 0 when there's a borrow, and 1 when there isn't
                break;

                case 0x0006:    // 8XY6: Shifts VX right by one. VF is set to the value of the least significant bit of VX before the shift
                break;

                case 0x0007:    // 8XY7: Sets VX to VY minus VX. VF is set to 0 when there's a borrow, and 1 when there isn't
                break;

                case 0x000E:    // 8XYE: Shifts VX left by one. VF is set to the value of the most significant bit of VX before the shift
                break;

                default:
                    console.log("Unknown opcode: " + opcode.toString(16));
            }
        break;

        case 0x9000:    // Skips the next instruction if VX doesn't equal VY
        break;

        case 0xA000:    // ANNN: sets I to the address NNN
            I = opcode & 0x0FFF;
            pc += 2;
        break;

        case 0xB000:    // BNNN: Jumps to the address NNN plus V0
        break;

        case 0xC000:    // CXNN: Sets VX to a random number and NN
        break;

        case 0xD000:    // DXYN: Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a height of N pixels.
                        //       Each row of 8 pixels is read as bit-coded (with the most significant bit of each byte displayed on the left) starting from memory location I;
                        //       I value doesn't change after the execution of this instruction.
                        //       As described above, VF is set to 1 if any screen pixels are flipped from set to unset when the sprite is drawn, and to 0 if that doesn't happen.
        break;

        case 0xE000:    // E---: more decoding
            switch( opcode & 0x00FF ){

                case 0x009E:    // EX9E: Skips the next instruction if the key stored in VX is pressed
                break

                case 0x00A1:    // EXA1: Skips the next instruction if the key stored in VX isn't pressed
                break;

                default:
                    console.log("Unknown opcode: " + opcode.toString(16));
            }
        break;

        case 0xF000:    // F000: more decoding
            switch( opcode & 0x00FF ){

                case 0x0007:    // FX07: Sets VX to the value of the delay timer
                break;

                case 0x000A:    // FX0A: A key press is awaited, and then stored in VX
                break;

                case 0x0015:    // FX15: Sets the delay timer to VX
                break;

                case 0x0018:    // FX19: Sets the sound timer to VX
                break;

                case 0x001E:    // FX1E: Adds VX to I
                break;

                case 0x0029:    // FX29: Sets I to the location of the sprite for the character in VX. Characters 0-F (in hexadecimal) are represented by a 4x5 font
                break;

                case 0x0033:    // FX33: Stores the Binary-coded decimal representation of VX, with
                                //       the most significant of three digits at the address in I,
                                //       the middle digit at I plus 1,
                                //       and the least significant digit at I plus 2
                break;

                case 0x0055:    // FX55: Stores V0 to VX in memory starting at address I
                break;

                case 0x0065:    // FX65: Fills V0 to VX with values from memory starting at address I
                break;

                default:
                    console.log("Unknown opcode: " + opcode.toString(16));
            }
        break;

        default:
            console.log("Unknown opcode: " + opcode.toString(16));
    }
}

function emulateCycle(){
    //Fetch opcode, instructions are 2 bytes long
    opcode = memory[pc] << 8 | memory[pc+1];
    //Decode and execute opcode

    //Update timers
}

function main(){
    memoryInit();

    //Emulation will begin once the game is loaded
}

//Load the game into the emulator memory
function loadGame(){
    for( i = 0; i < romFile.byteLength; i++ ){
        memoryView[0x200 + i] = romFile[i];
    }
}

function gameLoaded(){

    loadGame();
    for( i = 0; i < memory.byteLength; i++ ){
        console.log( memoryView[i] );
    }
    console.log('beginning emulation');
    //Emulation loop
    //while(true){
        //Emulate one cycle
        emulateCycle();

        //Draw to the screen

        //Get input
    //}
}
<commit_msg>implemented some opcodes<commit_after>//This is a chip-8 emulator
//Written by Jerry Schneider

//Load the fontset into memory at 0x50
function loadFontset(){
    for( i = 0; i < chip8_fontset.length; i++){
        memoryView[0x50 + i] = chip8_fontset[i];
    }
};

//Hardcoded fontset for the chip8
var chip8_fontset = [
  0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
  0x20, 0x60, 0x20, 0x20, 0x70, // 1
  0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
  0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
  0x90, 0x90, 0xF0, 0x10, 0x10, // 4
  0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
  0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
  0xF0, 0x10, 0x20, 0x40, 0x40, // 7
  0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
  0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
  0xF0, 0x90, 0xF0, 0x90, 0x90, // A
  0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
  0xF0, 0x80, 0x80, 0x80, 0xF0, // C
  0xE0, 0x90, 0x90, 0x90, 0xE0, // D
  0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
  0xF0, 0x80, 0xF0, 0x80, 0x80  // F
];

//Recieves messages from the font end
self.onmessage = function(event){
    //Begin emulation
    if(event.data == "start"){
        main();
    }
    //Kill the emulator
    else if(event.data == "stop"){
        self.close();
    }
};

//The current opcode
var opcode;

//4k memory
// 0x000-0x1FF - Chip 8 interpreter (contains font set in emu)
// 0x050-0x0A0 - Used for the built in 4x5 pixel font set (0-F)
// 0x200-0xFFF - Program ROM and work RAM
var memory = new ArrayBuffer(4096);

var memoryView = new Uint8Array(memory, 0);

//Registers
var V = [];

//Index register (upper 4 bits are unused)
var I = new ArrayBuffer(2);

//Program counter (upper 4 bits are unused)
var pc = new ArrayBuffer(2);

//Pixel Display 64 x 32
var pixels = [64 * 32];

//Timers which count down from X to 0 at 60hz
var delay_timer;
var sound_timer;

//16 frame stack
var stack = [16];
//Stack pointer
var sp;

//Key state
var key = [16];

function memoryInit(){
    //Init 16 8-bit registers
    for( i = 0; i < 16; i++ ){
        V.push( new ArrayBuffer(8) );
    }
    //Applications are expected to be loaded at 0x200
    pc = 0x200;

    //Clear memory
    opcode = 0;
    sp = 0;
    I = 0;

    //Load Fontset
    loadFontset();
}

function decodeAndExecute( opcode ){
    switch( opcode & 0xF000 ){

        case 0x0000:    // 0---: more decoding
            switch( opcode & 0x000F ){

                case 0x0000:    // 0x00E0: clear the screen
                break;

                case 0x000E:    // 0x00EE: return from a subroutine
                    pc = stack[--sp];
                break;

                default:
                    console.log("Unknown opcode: " + opcode.toString(16));
            }
        break;

        case 0x1000:    // 1NNN: Jumps to address NNN
            pc = 0x0FFF & opcode;
        break

        case 0x2000:    // 2NNN: Calls subroutine at address NNN
            stack[sp++] = pc;
            pc = 0x0FFF & opcode;
        break;

        case 0x3000:    // 3XNN: Skips the next instrouction if VX equals NN
            if( V[ (0x0F00 & opcode) >> 8 ] == 0x00FF & opcode ){
                pc += 4;
            }
            else{
                pc += 2;
            }
        break;

        case 0x4000:    // 4XNN: Skips the next instrouction if VX does not equal NN
            if( V[ (0x0F00 & opcode) >> 8 ] != 0x00FF & opcode ){
                pc += 4;
            }
            else{
                pc += 2;
            }
        break;

        case 0x5000:    // 5XY0: Skips the next instrouction if VX equals VY
            if( V[ (0x0F00 & opcode) >> 8 ] == V[ (0x00F0 & opcode) >> 4 ] ){
                pc += 4;
            }
            else{
                pc += 2;
            }
        break;

        case 0x6000:    // 6XNN: Sets VX to NN
            V[ (0x0F00 & opcode) >> 8 ] = 0x00FF & opcode;
            pc += 2;
        break;

        case 0x7000:    // 7XNN: Adds NN to VX
            V[ (0x0F00 & opcode) >> 8 ] += 0x00FF & opcode;
            pc += 2;
        break;

        case 0x8000:    // 8---: more decoding
            switch( opcode & 0x000F ){
                case 0x0000:    // 8XY0: Sets VX to the value of VY
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x00F0 & opcode) >> 4 ];
                    pc += 2;
                break;

                case 0x0001:    // 8XY1: Sets VX to VX | VY
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x0F00 & opcode) >> 8 ] | V[ (0x00F0 & opcode) >> 4 ];
                    pc += 2;
                break;

                case 0x0002:    // 8XY2: Sets VX to VX & VY
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x0F00 & opcode) >> 8 ] & V[ (0x00F0 & opcode) >> 4 ];
                    pc += 2;
                break;

                case 0x0003:    // 8XY3: Sets VX to VX XOR VY
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x0F00 & opcode) >> 8 ] XOR V[ (0x00F0 & opcode) >> 4 ];
                    pc += 2;
                break;

                case 0x0004:    // 8XY4: Adds VY to VX. VF is set to 1 when there's a carry, and to 0 when there isn't
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x0F00 & opcode) >> 8 ] + V[ (0x00F0 & opcode) >> 4 ];
                    V[ 0xF ] = ( V[ (0x0F00 & opcode) >> 8 ] & 0x100 ) >> 9;
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x0F00 & opcode) >> 8 ] & 0x00FF;
                    pc += 2;
                break;

                case 0x0005:    // 8XY5: VY is subtracted from VX. VF is set to 0 when there's a borrow, and 1 when there isn't
                    V[ (0x0F00 & opcode) >> 8 ] += 0x100;
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x0F00 & opcode) >> 8 ] - V[ (0x00F0 & opcode) >> 4 ];
                    V[ 0xF ] = (V[ (0x0F00 & opcode) >> 8 ] & 0x100) >> 9;
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x0F00 & opcode) >> 8 ] & 0x00FF;
                    pc += 2;
                break;

                case 0x0006:    // 8XY6: Shifts VX right by one. VF is set to the value of the least significant bit of VX before the shift
                    V[ 0xF ] = V[ (0x0F00 & opcode) >> 8 ] & 0x1;
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x0F00 & opcode) >> 8 ] >> 1;
                    pc += 2;
                break;

                case 0x0007:    // 8XY7: Sets VX to VY minus VX. VF is set to 0 when there's a borrow, and 1 when there isn't
                    V[ (0x00F0 & opcode) >> 4 ] += 0x100;
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x00F0 & opcode) >> 4 ] - V[ (0x0F00 & opcode) >> 8 ];
                    V[ 0xF ] = (V[ (0x00F0 & opcode) >> 4 ] & 0x100) >> 9;
                    V[ (0x00F0 & opcode) >> 4 ] = V[ (0x00F0 & opcode) >> 4 ] & 0x00FF;
                    pc += 2;
                break;

                case 0x000E:    // 8XYE: Shifts VX left by one. VF is set to the value of the most significant bit of VX before the shift
                    V[ 0xF ] = V[ (0x0F00 & opcode) >> 8 ] & 0x80;
                    V[ (0x0F00 & opcode) >> 8 ] = V[ (0x0F00 & opcode) >> 8 ] << 1;
                    pc += 2;
                break;

                default:
                    console.log("Unknown opcode: " + opcode.toString(16));
            }
        break;

        case 0x9000:    // Skips the next instruction if VX doesn't equal VY
        break;

        case 0xA000:    // ANNN: sets I to the address NNN
            I = opcode & 0x0FFF;
            pc += 2;
        break;

        case 0xB000:    // BNNN: Jumps to the address NNN plus V0
        break;

        case 0xC000:    // CXNN: Sets VX to a random number and NN
        break;

        case 0xD000:    // DXYN: Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a height of N pixels.
                        //       Each row of 8 pixels is read as bit-coded (with the most significant bit of each byte displayed on the left) starting from memory location I;
                        //       I value doesn't change after the execution of this instruction.
                        //       As described above, VF is set to 1 if any screen pixels are flipped from set to unset when the sprite is drawn, and to 0 if that doesn't happen.
        break;

        case 0xE000:    // E---: more decoding
            switch( opcode & 0x00FF ){

                case 0x009E:    // EX9E: Skips the next instruction if the key stored in VX is pressed
                break

                case 0x00A1:    // EXA1: Skips the next instruction if the key stored in VX isn't pressed
                break;

                default:
                    console.log("Unknown opcode: " + opcode.toString(16));
            }
        break;

        case 0xF000:    // F000: more decoding
            switch( opcode & 0x00FF ){

                case 0x0007:    // FX07: Sets VX to the value of the delay timer
                break;

                case 0x000A:    // FX0A: A key press is awaited, and then stored in VX
                break;

                case 0x0015:    // FX15: Sets the delay timer to VX
                break;

                case 0x0018:    // FX19: Sets the sound timer to VX
                break;

                case 0x001E:    // FX1E: Adds VX to I
                break;

                case 0x0029:    // FX29: Sets I to the location of the sprite for the character in VX. Characters 0-F (in hexadecimal) are represented by a 4x5 font
                break;

                case 0x0033:    // FX33: Stores the Binary-coded decimal representation of VX, with
                                //       the most significant of three digits at the address in I,
                                //       the middle digit at I plus 1,
                                //       and the least significant digit at I plus 2
                break;

                case 0x0055:    // FX55: Stores V0 to VX in memory starting at address I
                break;

                case 0x0065:    // FX65: Fills V0 to VX with values from memory starting at address I
                break;

                default:
                    console.log("Unknown opcode: " + opcode.toString(16));
            }
        break;

        default:
            console.log("Unknown opcode: " + opcode.toString(16));
    }
}

function emulateCycle(){
    //Fetch opcode, instructions are 2 bytes long
    opcode = memory[pc] << 8 | memory[pc+1];
    //Decode and execute opcode

    //Update timers
}

function main(){
    memoryInit();

    //Emulation will begin once the game is loaded
}

//Load the game into the emulator memory
function loadGame(){
    for( i = 0; i < romFile.byteLength; i++ ){
        memoryView[0x200 + i] = romFile[i];
    }
}

function gameLoaded(){

    loadGame();
    for( i = 0; i < memory.byteLength; i++ ){
        console.log( memoryView[i] );
    }
    console.log('beginning emulation');
    //Emulation loop
    //while(true){
        //Emulate one cycle
        emulateCycle();

        //Draw to the screen

        //Get input
    //}
}
<|endoftext|>


<commit_before>class Enemy {
  constructor() {
    const enemy = DontPanic.game.add.sprite(-10, 20, 'enemyShip');
    enemy.scale.x = 0.2;
    enemy.scale.y = 0.2;
    enemy.fixedToCamera = true;
    DontPanic.game.physics.arcade.enable(enemy);
    enemy.body.collideWorldBounds = false;
    this.enemySprite = enemy;
  }

  moveEnemy() {
    this.enemySprite.cameraOffset.x += 1;
  }

}

class Whale {
  constructor() {
    const whale = DontPanic.game.add.sprite(DontPanic.game.world.width/2 - 16, -350, 'whale');
    whale.scale.x = 0.3;
    whale.scale.y = 0.3;
    DontPanic.game.physics.arcade.enable(whale);
    whale.body.collideWorldBounds = false;
    whale.body.gravity.y = 20;
    whale.body.velocity.y = 10;
    this.whaleSprite = whale;
  }
}

class Petunias {
}

class Earth {

}

class Fueltanks {

}
<commit_msg>spawn whale more randomly<commit_after>class Enemy {
  constructor() {
    const enemy = DontPanic.game.add.sprite(-10, 20, 'enemyShip');
    enemy.scale.x = 0.2;
    enemy.scale.y = 0.2;
    enemy.fixedToCamera = true;
    DontPanic.game.physics.arcade.enable(enemy);
    enemy.body.collideWorldBounds = false;
    this.enemySprite = enemy;
  }

  moveEnemy() {
    this.enemySprite.cameraOffset.x += 1;
  }

}

class Whale {
  constructor() {
    let randomHeight = (Math.floor(Math.random() * 5000) + 500)
    const whale = DontPanic.game.add.sprite(DontPanic.game.world.width/2 - 16, -(randomHeight), 'whale');
    whale.scale.x = 0.3;
    whale.scale.y = 0.3;
    DontPanic.game.physics.arcade.enable(whale);
    whale.body.collideWorldBounds = false;
    whale.body.gravity.y = randomHeight / 100;
    this.whaleSprite = whale;
  }
}

class Petunias {
}

class Earth {

}

class Fueltanks {

}
<|endoftext|>