From 63ae6b7b826cc9728e2204cdea0fea92e99a627d Mon Sep 17 00:00:00 2001
From: Evan Pratten <ewpratten@gmail.com>
Date: Fri, 17 Apr 2020 14:18:27 -0400
Subject: [PATCH] move all files to their own folder

---
 LICENSE => docs/LICENSE            |    0
 index.html => docs/index.html      |   48 +-
 pixelmix.ttf => docs/pixelmix.ttf  |  Bin
 {scripts => docs/scripts}/game.js  | 2124 ++++++++++++++--------------
 {scripts => docs/scripts}/index.js |   56 +-
 5 files changed, 1114 insertions(+), 1114 deletions(-)
 rename LICENSE => docs/LICENSE (100%)
 rename index.html => docs/index.html (96%)
 rename pixelmix.ttf => docs/pixelmix.ttf (100%)
 rename {scripts => docs/scripts}/game.js (97%)
 rename {scripts => docs/scripts}/index.js (86%)

diff --git a/LICENSE b/docs/LICENSE
similarity index 100%
rename from LICENSE
rename to docs/LICENSE
diff --git a/index.html b/docs/index.html
similarity index 96%
rename from index.html
rename to docs/index.html
index 09bb064..cd14837 100644
--- a/index.html
+++ b/docs/index.html
@@ -1,25 +1,25 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <!-- <link rel="icon" type="image/gif" href="icon.png"/> -->
-        <title>title</title>
-        <style>
-            html {
-                background-color: #242424;
-                color: white;
-            }
-            canvas {
-                position:absolute;
-                top:0;bottom:0;right:0;left:0;
-                margin:auto;
-                border: 5px solid rgb(63, 63, 63); 
-                border-radius: 10px;
-            }
-        </style>
-    </head>
-    <body>
-        <canvas width="1000" height="800" id="game"></canvas>
-        <script src="scripts/game.js"></script>
-        <script src="scripts/index.js"></script>
-    </body>
+<!DOCTYPE html>
+<html>
+    <head>
+        <!-- <link rel="icon" type="image/gif" href="icon.png"/> -->
+        <title>title</title>
+        <style>
+            html {
+                background-color: #242424;
+                color: white;
+            }
+            canvas {
+                position:absolute;
+                top:0;bottom:0;right:0;left:0;
+                margin:auto;
+                border: 5px solid rgb(63, 63, 63); 
+                border-radius: 10px;
+            }
+        </style>
+    </head>
+    <body>
+        <canvas width="1000" height="800" id="game"></canvas>
+        <script src="scripts/game.js"></script>
+        <script src="scripts/index.js"></script>
+    </body>
 </html>
\ No newline at end of file
diff --git a/pixelmix.ttf b/docs/pixelmix.ttf
similarity index 100%
rename from pixelmix.ttf
rename to docs/pixelmix.ttf
diff --git a/scripts/game.js b/docs/scripts/game.js
similarity index 97%
rename from scripts/game.js
rename to docs/scripts/game.js
index e9c1394..dcd3fee 100644
--- a/scripts/game.js
+++ b/docs/scripts/game.js
@@ -1,1063 +1,1063 @@
-function createCanvas(id) {
-    var tempCanvas = document.createElement("canvas");
-    tempCanvas.id = id;
-    tempCanvas.width = canvases.cvs.width;
-    tempCanvas.height = canvases.cvs.height;
-    tempCanvas.style = "image-rendering:pixelated;image-rendering: crisp-edges;display:none";//display:none;
-
-    document.body.appendChild(tempCanvas);
-
-    canvases[`${id}cvs`] = document.getElementById(id);
-    canvases[`${id}ctx`] = canvases[`${id}cvs`].getContext("2d");
-}
-
-function startLoops() {
-    try {draw} catch (err){console.warn(bug+" no draw function found");return null;}
-    try {update} catch (err){console.warn(bug+" no update function found");return null;}
-    try {input} catch (err){seperateInputLoop=false;}
-    onAssetsLoaded();
-
-    requestAnimationFrame(drawLoop);
-    setInterval(updateLoop,1000/updateFPS);
-
-    if(seperateInputLoop) {
-        setInterval(inputLoop,4);
-    }
-}
-
-function mousePosition() {
-    if(drawMode===0) {
-        return {x:(mousePos.x)-camera.x,y:(mousePos.y)-camera.y};
-    } else if(drawMode===1) {
-        var xoff = canvases.cvs.width/2;
-        var yoff = canvases.cvs.height/2;
-        return {x:((mousePos.x-xoff)/camera.zoom+xoff)-camera.x,y:((mousePos.y-yoff)/camera.zoom+yoff)-camera.y};
-    } else {
-        var xoff = canvases.cvs.width/2;
-        var yoff = canvases.cvs.height/2;
-        var tempPos = {x:((mousePos.x-xoff)/camera.zoom+xoff)-camera.x,y:((mousePos.y-yoff)/camera.zoom+yoff)-camera.y};
-
-        var center = {x:-camera.x + cw/2, y:-camera.y + ch/2};
-        var tempAngle = pointTo(center,tempPos) - camera.angle; 
-        var tempDist = dist(center,tempPos);
-
-        return {x:center.x + (Math.cos(tempAngle) * tempDist),y:center.y + (Math.sin(tempAngle) * tempDist)}
-    }
-}
-
-function addStyle() {
-    var tempStyle = document.createElement("style");
-    tempStyle.id="gamejsstyle";
-    document.head.appendChild(tempStyle);
-    var tempMeta = document.createElement("meta");
-    tempMeta.setAttribute("charset","utf-8");
-    document.head.appendChild(tempMeta);
-}
-
-function rand(min,max) {
-    return Math.floor(Math.random() * (max - min + 1)) + min;
-}
-
-function radToDeg(rad) {return rad / Math.PI * 180;}
-function degToRad(deg) {return deg * Math.PI / 180;}
-
-function velocity(angle) {
-    return {x:Math.sin(angle),y:Math.cos(angle)};
-}
-
-function pointTo(point,targetPoint) {
-    var adjacent = (targetPoint.x - point.x);
-    var opposite = (targetPoint.y - point.y);
-    var h = Math.atan2(opposite, adjacent);
-    return h;
-}
-
-function loadImagesAndSounds() {
-    var curpath="";
-    context = new AudioContext();
-    sfxVolumeNode = context.createGain();
-    sfxVolumeNode.connect(context.destination);
-    bmgVolumeNode = context.createGain();
-    bmgVolumeNode.connect(context.destination);
-    deeper(images,"image");
-    deeper(audio,"sound");
-    function deeper(curpos,type) {
-        let addedPath="";
-        for(let j=0;j<curpos.length;j++) {
-            if(typeof curpos[j]=="string") {
-                if(j==0) {
-                    curpath+=curpos[j];
-                    addedPath = curpos[j];
-                } else {
-                    if(type=="image") {
-                        let name = curpath + curpos[j];
-                        imagePaths.push(name);
-                        let temp = new Image();
-                        temp.src = name;
-                        temp.onerror = function () {
-                            console.warn(bug+" "+this.src + " was not found");
-                        };
-                        temp.onload = function() {spriteLoad(name,temp);}
-                        imgs.push(temp);
-                    } else if(type=="sound") {
-                        audioPaths.push(curpath + curpos[j]);
-                        newSound(curpath + curpos[j]);
-                    }
-                }
-            }
-            if(typeof curpos[j]=="object") {
-               deeper(curpos[j],type);
-            }
-        }
-        curpath = curpath.slice(0,curpath.length-addedPath.length);
-    }
-    
-    loadingCircle = new Image();
-    loadingCircle.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAf0lEQVQ4jc2SuxHAIAxDbY4pMpHmyJSeKGuQKpyj2Hy6qETPQvhQCWRmDRfeZ4cJAGW28mAUyL4Pqmx2nfK+zaR59glRHo5qZi0BaPHmbDhiyuzdsza9wcrtEVtG4Ip+FLCzTM+WneWxPv9gpQUzmhncLPOHUCYfHr4/C4r2dQPfhkeIbjeYWgAAAABJRU5ErkJggg==";
-    clickSound = new Audio("data:audio/x-wav;base64,UklGRowBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YWgBAADa/6T/2/+S/x//pP769Xr4fPh5+H34evh7+Pv6gf18/QIAhQcIDxUZFR4VHhgeEx6TFgkPCgqAAnz49/X18HLu7ubo4eXc5dzj3Gjf5+Fr5G7pce759YECiwwRFBQZlxuXG5cbFRmTFo8RCAoAAPz69/X08G7udO5s7vz1dvj++nv9gP3+/wEAgwKBAogHkBEpLUNG1lzqcPV683r4eu51ZmnVV7w+qypy88fDoKAXlAqKBoUAgIeHlpYsrTu87Ot9/ZIRGxkoKDEtqionIxgZiwfj5lnaz9JN0E3QV9pd3+Tm9fUBAAQFBwWNDBEPFxSYFpsWEA9+/fP1dfNt83bz8fX9+gQFkAwPDxQPEQ+IBwIAdfjv8OLm2+HX3Nrh4+bm63n4BAUUDx0ZqyCrJSkelBGEAnb4a+5a5Njcztxc31jkZunx9QgFGhQfGa0gqCCuIKkgpRsaFIsHdfhj6dfh0NzM19Th6es=");
-    let pos = {x:cw/2-100,y:ch/2-100};
-    optionsButtons.screenSize = {x:pos.x+160,y:pos.y+12,w:50,h:20};
-    optionsButtons.sfx = {x:pos.x+125,y:pos.y+40,w:120,h:20};
-    optionsButtons.bmg = {x:pos.x+125,y:pos.y+70,w:120,h:20};
-    loadLoop();
-}
-
-function loadLoop() {
-    if(Object.keys(sprites).length == imagePaths.length && audioPaths.length == audioLoadedLength) {
-        startLoops();
-        imagePaths=[];
-        audioPaths=[];
-        imgs=[];
-    } else {
-        curCtx.fillStyle="#2d2d2d";
-        curCtx.fillRect(0,0,cw,ch);
-        text(`audio:   ${audioLoadedLength}/${audioPaths.length}`,10,30,"white",2);
-        text(`sprites: ${Object.keys(sprites).length}/${imagePaths.length}`,10,10,"white",2);
-        curCtx.setTransform(1, 0, 0, 1, Math.round(cw/2), Math.round(ch/2));
-        curCtx.rotate(loadAng);
-        loadAng+=0.1;
-        curCtx.drawImage(loadingCircle,Math.round(-8),Math.round(-8));
-        curCtx.setTransform(1, 0, 0, 1, 0, 0);
-        requestAnimationFrame(loadLoop);
-    }
-}
-
-function spriteLoad(path,image) {
-    let startpos;
-    let endpos = path.lastIndexOf(".");
-    for(let j=endpos-1;acceptableChars.includes(path[j]);j--) {startpos=j;}
-    let spriteName = path.slice(startpos,endpos)
-    let dsize=Math.max(image.width,image.height)/2;
-    sprites[spriteName] = {spr:image,drawLimitSize:dsize};
-    
-}
-
-function newSound(src) {
-    let startpos;
-    let endpos = src.lastIndexOf(".");
-    for(let j=endpos-1;acceptableChars.includes(src[j]);j--) {startpos=j;}
-    let soundName = src.slice(startpos,endpos); 
-    sounds[soundName] = {nodes:[],volNodes:[],src:src,type:"sfx",volume:1};
-    sounds[soundName].nodes = [1];
-
-    let loadingSound = new Audio();
-    loadingSound.onerror = function () {
-        console.warn(bug+" "+ src + " was not found");
-    };
-    loadingSound.src = src;
-    loadingSound.preload='auto';
-    loadingSound.addEventListener('canplaythrough', function() { 
-        audioLoadedLength++;
-     }, false);
-    sounds[soundName].nodes.push(loadingSound);
-
-    let soundNode = context.createMediaElementSource(loadingSound);
-    let gainNode = context.createGain();
-
-    soundNode.connect(gainNode);
-    gainNode.connect(sfxVolumeNode);
-
-    abuffer.push(soundNode);
-    volumeList.push(gainNode);
-    sounds[soundName].volNodes.push(volumeList.length-1);
-}
-
-function addSound(sound) {
-    let loadingSound = new Audio();
-    loadingSound.src = sound.src;
-    loadingSound.preload='auto';
-    sound.nodes.splice(sound.nodes[0],0,loadingSound);
-
-    let soundNode = context.createMediaElementSource(loadingSound);
-    let gainNode = context.createGain();
-    gainNode.gain.value=sound.volume;
-
-    soundNode.connect(gainNode);
-    gainNode.connect(sound.type=="sfx"?sfxVolumeNode:bmgVolumeNode);
-
-    abuffer.push(soundNode);
-    volumeList.push(gainNode);
-    sound.volNodes.push(volumeList.length-1);
-
-    volumeList[sound.volNodes[sound.volNodes.length-1]].gain.value = volumeList[sound.volNodes[0]].gain.value
-}
-
-
-
-function play(sound) {
-    s=sound.nodes;
-    if(s[s[0]].ended || !(s[s[0]].played.length)) {
-        s[s[0]].play();
-        s[0]++;
-        if(s[0]==s.length) {
-            s[0]=1;
-        }
-    } else {
-        addSound(sound);
-        s[s[0]].play();
-        s[0]++;
-        if(s[0]==s.length) {
-            s[0]=1;
-        }
-    }
-}
-
-function setVolume(sound,volume) {
-    for(let i=0,l=sound.volNodes.length;i<l;i++) {
-        volumeList[sound.volNodes[i]].gain.value = volume;
-    }
-}
-
-function setType(sound,newType) {
-    for(let i=0,l=sound.volNodes.length;i<l;i++) {
-        volumeList[sound.volNodes[i]].disconnect(sound.type=="sfx"?sfxVolumeNode:bmgVolumeNode);
-        volumeList[sound.volNodes[i]].connect(newType=="sfx"?sfxVolumeNode:bmgVolumeNode);
-    }
-    sound.type = newType;
-}
-
-function stop(sound) {
-    s=sound.nodes;
-    for(let i=1;i<s.length;i++) {
-        s[i].pause();
-        s[i].currentTime = 0;
-    }
-}
-
-function handleOptionsInput() {
-    let ImTierdMakemenuwork=true;
-    if(optionsMenu) {
-        if(mousePress[0]) {
-            if(rectpoint(optionsButtons.screenSize,mousePos)) {
-                if(screenSize=="1:1") {
-                    screenSize = "fit";
-                    canvasScale=0;
-                } else {
-                    screenSize = "1:1";
-                    canvasScale=1;
-                }
-            }
-            if(!rectpoint({x:cw/2,y:ch/2,w:200,h:200},mousePos)) {
-                optionsMenu=false;
-                ImTierdMakemenuwork=false;
-            }
-        }
-        if(mouseDown[0]) {
-            if(rectpoint(optionsButtons.sfx,mousePos)) {
-                volume.sfx = (mousePos.x-(optionsButtons.sfx.x-60))/120;
-            }
-            if(rectpoint(optionsButtons.bmg,mousePos)) {
-                volume.bgm = (mousePos.x-(optionsButtons.bmg.x-60))/120;
-            }
-        }
-    }
-    if(mousePos.x>cw-32&&mousePos.y<32) {
-        if(mousePress[0]&&ImTierdMakemenuwork) {
-            clickSound.play();
-            paused=true;
-            optionsMenu=!optionsMenu;
-        }
-        optionsHover = 25;
-    } else {
-        optionsHover = 0;
-    }
-    if(mousePos.x<cw-32&&mousePos.x>cw-64&&mousePos.y<32) {
-        pauseHover = 25;
-        if(mousePress[0]) {
-            clickSound.play();
-            paused=!paused;
-        }
-    } else {
-        pauseHover = 0;
-    }
-    
-}
-function addFont() {
-    var tempStyle = document.createElement("style");
-    tempStyle.innerHTML = `
-    @font-face {
-        font-family: 'PixelArial11';
-        src: url("./pixelmix.ttf") format('truetype');
-        font-weight: 900;
-        font-style: normal;
-    
-    }
-    html {font-family: 'PixelArial11' !important; font-size: 16px;}
-    `;
-    document.head.appendChild(tempStyle);
-    canvases.ctx.textBaseline = "hanging";
-    canvases.ctx.textAlign = "left";
-}
-var scaleDefault = 1;
-function img(img,x,y,angle=0,sx=scaleDefault,sy=scaleDefault) {
-    var half = img.drawLimitSize;
-    if((x+half>drawLimitLeft&&x-half<drawLimitRight&&y+half>drawLimitTop&&y-half<drawLimitBottom)||absDraw) {
-        let spr = img.spr;
-        if(angle===0&&sx===1&&sy===1) {
-            curCtx.drawImage(spr,Math.round(x+camera.x+difx-(spr.width/2)),Math.round(y+camera.y+dify-(spr.height/2)));
-        } else {
-            curCtx.setTransform(sx, 0, 0, sy, Math.round(x+camera.x+difx), Math.round(y+camera.y+dify));
-            curCtx.rotate(angle);
-            curCtx.drawImage(spr,Math.round(-spr.width/2),Math.round(-spr.height/2));
-            curCtx.setTransform(1, 0, 0, 1, 0, 0);
-        }
-    }
-}
-
-function imgIgnoreCutoff(img,x,y,angle=0,sx=1,sy=1) {
-    let spr = img.spr;
-    if(angle===0&&sx===1&&sy===1) {
-        curCtx.drawImage(spr,Math.round(x+camera.x+difx-(spr.width/2)),Math.round(y+camera.y+dify-(spr.height/2)));
-    } else {
-        curCtx.setTransform(sx, 0, 0, sy, Math.round(x+camera.x+difx), Math.round(y+camera.y+dify));
-        curCtx.rotate(angle);
-        curCtx.drawImage(spr,Math.round(-spr.width/2),Math.round(-spr.height/2));
-        curCtx.setTransform(1, 0, 0, 1, 0, 0);
-    }
-}
-
-function rect(x,y,w,h,color) {
-    curCtx.fillStyle = color;
-    curCtx.fillRect(x-(w/2)+camera.x+difx,y-(h/2)+camera.y+dify,w,h);
-}
-
-function circle(x,y,r,color) {
-    curCtx.beginPath();
-    curCtx.arc(x+camera.x+difx, y+camera.y+dify, r, 0, 2 * Math.PI, false);
-    curCtx.fillStyle = color;
-    curCtx.fill();
-}
-
-function shape(x,y,relitivePoints,color) {
-    x+=camera.x+difx;
-    y+=camera.y+dify;
-    curCtx.fillStyle = color;
-    curCtx.beginPath();
-    curCtx.moveTo(x+relitivePoints[0].x, y+relitivePoints[0].y);
-    for(let i=1,l=relitivePoints.length;i<l;i++) {
-        curCtx.lineTo(x+relitivePoints[i].x, y+relitivePoints[i].y);
-    }
-    curCtx.fill();
-}
-
-function text(txt,x,y,color="black",size=1,maxWidth=cw) {
-    txt = txt.toString();
-    curCtx.fillStyle = color;
-    curCtx.font = `${Math.round(size)*8}px PixelArial11`;
-                                                                                        //I hate text wrapping now 
-    var txtList = txt.split("\n");                                                      //split string on enters
-    for(let i=0;i<txtList.length;i++) {                                                 //go through array of strings
-        if(curCtx.measureText(txtList[i]).width>maxWidth) {                             //if the string is too big, divide up into smaller strings
-            var tempTxt = txtList[i].split(" ");                                        //split into individual words
-            var tempStr="";                                                             //string for measuring size
-            var addAmount=0;                                                            //track where in the txtList we are
-            txtList.splice(i,1);                                                        //remove the too long string
-            for(let j=0;j<tempTxt.length;j++) {                                         //go through the split up string
-                if(curCtx.measureText(tempStr + tempTxt[j] + " ").width<maxWidth) {     //if adding a word doesn't make tempStr too long, add it, other wise, add tempStr to txtList;
-                    tempStr += tempTxt[j] + " ";
-                } else {
-                    if(j==0) {tempStr+=tempTxt[j];}                                     //if we are here when j is 0, we have one word that is longer then the maxWidth, so we just draw it
-                    txtList.splice(i+addAmount,0,tempStr);                              //put tempStr in txtList
-                    addAmount++;                                                        //move the position we put the tempStr in
-                    tempStr="";                                                         //reset tempStr
-                    tempTxt.splice(0,(j==0?1:j));                                       //delete words that have been used
-                    j=-1;                                                               //make it so in the next loop, j starts at 0
-                }
-            }
-            if(tempStr.length!=0) {
-                txtList.splice(i+addAmount,0,tempStr);                                  //add any leftover text
-            }
-        }
-    }
-
-    for(let i=0;i<txtList.length;i++) {
-        curCtx.fillText(txtList[i],x+camera.x+difx,y+camera.y+dify+((i+(drawMode?1:0))*8*size+(size*i)));
-    }
-}
-
-function textWidth(txt,size=1) {
-    txt = txt.toString();
-    curCtx.font = `${Math.round(size)*8}px PixelArial11`;
-    return curCtx.measureText(txt).width;
-}
-
-function centerCameraOn(x,y) {
-    camera.x = -x+canvases.cvs.width/2;
-    camera.y = -y+canvases.cvs.height/2;
-}
-
-function moveCamera(x,y) {
-    camera.x -= y * Math.sin(camera.angle);
-    camera.y -= y * Math.cos(camera.angle);
-    camera.x -= x * Math.sin(camera.angle + 1.57079632);
-    camera.y -= x * Math.cos(camera.angle + 1.57079632);
-}
-
-function imgRotScale(x,y,angle,scale,pic,ctx) { //used for camera movement
-    ctx.setTransform(scale, 0, 0, scale, x, y);
-    ctx.rotate(angle);
-    ctx.drawImage(pic,-pic.width/2,-pic.height/2);
-    ctx.setTransform(1, 0, 0, 1, 0, 0);
-}
-
-function drawCursor() {
-    if(cursor.sprite&&mouseOnCanvas) {
-        if(cursor.alignment) {
-            canvases.ctx.drawImage(cursor.sprite.spr,mousePos.x-Math.round(cursor.sprite.spr.width/2),mousePos.y-Math.round(cursor.sprite.spr.height/2));
-        } else {
-            canvases.ctx.drawImage(cursor.sprite.spr,mousePos.x,mousePos.y);
-        }
-        cursor.show = false;
-    } else {
-        cursor.show = true;
-    }
-}
-
-function render() {
-    if(drawMode===1) {
-        imgRotScale(canvases.cvs.width/2,canvases.cvs.height/2,0,camera.zoom,canvases.buffer1cvs,canvases.ctx);
-    }
-    if(drawMode===2) {
-        imgRotScale(canvases.cvs.width/2,canvases.cvs.height/2,camera.angle,1,canvases.buffer2cvs,canvases.buffer1ctx);
-        imgRotScale(canvases.cvs.width/2,canvases.cvs.height/2,0,camera.zoom,canvases.buffer1cvs,canvases.ctx);
-    }
-}
-
-function clearCanvases() {
-    canvases.ctx.clearRect(0,0,canvases.cvs.width,canvases.cvs.height);
-    canvases.buffer1ctx.clearRect(0,0,canvases.buffer1cvs.width,canvases.buffer1cvs.height);
-    canvases.buffer2ctx.clearRect(0,0,canvases.buffer2cvs.width,canvases.buffer2cvs.height);
-}
-
-function switchDrawMode() {
-    if(camera.zoom<1) {camera.zoom=1;}
-    if(camera.angle!=0) {
-        drawMode=2;
-    } else if(camera.zoom!=1) {
-        drawMode=1;
-    } else {
-        drawMode=0;
-    }
-    switch (drawMode) {
-        case 0: curCtx = canvases.ctx; break;
-        case 1: curCtx = canvases.buffer1ctx; break;
-        case 2: curCtx = canvases.buffer2ctx; break;
-    }
-}
-
-function resizeBuffers() {
-    var tempSize = maxCvsSize/camera.zoom;
-    var tempSizeAndPadding = tempSize + (tempSize/2)
-
-    canvases.buffer2cvs.width = tempSizeAndPadding;
-    canvases.buffer2cvs.height = tempSizeAndPadding;
-    
-    if(drawMode===2) {
-        difx = (canvases.buffer2cvs.width - canvases.cvs.width)/2;
-        dify = (canvases.buffer2cvs.height - canvases.cvs.height)/2;
-    } else {
-        difx=0;
-        dify=0;
-    }
-    canvases.buffer2ctx.imageSmoothingEnabled = false;
-}
-
-function scaleCanvases() { //scales canvas by canvas scale, if scale is 0, canvas will try to fit screen
-    var style = document.getElementById("gamejsstyle");
-    if(canvasScale==0) {
-        var tempScale = Math.min(Math.floor(window.innerWidth/canvases.cvs.width),Math.floor(window.innerHeight/canvases.cvs.height));
-        tempScale=tempScale<1?1:tempScale;
-        autoScale=tempScale;
-        style.innerHTML = `#game {image-rendering:pixelated;image-rendering: crisp-edges;width:${tempScale*canvases.cvs.width}px;cursor: ${cursor.show?"crosshair":"none"};}`;
-    } else {
-        style.innerHTML = `#game {image-rendering:pixelated;image-rendering: crisp-edges;width:${Math.floor(canvasScale*canvases.cvs.width)}px;cursor: ${cursor.show?"crosshair":"none"};}`;
-    }
-}
-
-function drawButtons() {
-    let pos = {x:cw-16,y:16}; 
-    //options
-    rect(pos.x,pos.y,34,34,"#9c9c9c");
-    let c = optionsHover+45;
-    rect(pos.x,pos.y,32,32,`rgb(${c},${c},${c})`);
-    c = optionsHover + 69;
-    let cc = `rgb(${c},${c},${c})`;
-    rect(pos.x,pos.y-6,26,4,cc);
-        rect(pos.x-6,pos.y-6,4,8,cc);
-    rect(pos.x,pos.y+6,26,4,cc);
-        rect(pos.x+11,pos.y+6,4,8,cc);
-    //pause
-    pos.x-=33;
-    rect(pos.x,pos.y,34,34,"#9c9c9c");
-    c = pauseHover+45;
-    rect(pos.x,pos.y,32,32,`rgb(${c},${c},${c})`);
-    c = pauseHover + 69;
-    cc = `rgb(${c},${c},${c})`;
-    if(paused) {
-        shape(pos.x,pos.y,[{x:-7,y:-10},{x:-7,y:10},{x:10,y:0}],cc);
-    } else {
-        rect(pos.x+6,pos.y,6,20,cc);
-        rect(pos.x-6,pos.y,6,20,cc);
-    }
-}
-
-function drawOptionsMenu() {
-    if(optionsMenu) {
-        let pos = {x:cw/2-100,y:ch/2-100};
-        rect(cw/2,ch/2,200,200,"#242424");
-        text("Screen Size:",pos.x+2,pos.y+2,"white",2);
-            let b = optionsButtons.screenSize;
-            rect(b.x,b.y,b.w,b.h,"#444444");
-            text(screenSize,pos.x+145,pos.y+4,"white",2);
-        text("sfx",pos.x+2,pos.y+30,"white",2);
-            b = optionsButtons.sfx;
-            rect(b.x,b.y,b.w,b.h-10,"#444444");
-            rect((b.x-60)+(volume.sfx*120),b.y,8,20,"#444444");
-        text("bmg",pos.x+2,pos.y+60,"white",2);
-            b = optionsButtons.bmg;
-            rect(b.x,b.y,b.w,b.h-10,"#444444");
-            rect((b.x-60)+(volume.bgm*120),b.y,8,20,"#444444");
-    }
-}
-var k={a:65,b:66,c:67,d:68,e:69,f:70,g:71,h:72,i:73,j:74,k:75,l:76,m:77,n:78,o:79,p:80,q:81,r:82,s:83,t:84,u:85,v:86,w:87,x:88,y:89,z:90,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,BACKTICK:192,MINUS:189,EQUALS:187,OPENSQUARE:219,ENDSQUARE:221,SEMICOLON:186,SINGLEQUOTE:222,BACKSLASH:220,COMMA:188,PERIOD:190,SLASH:191,ENTER:13,BACKSPACE:8,TAB:9,CAPSLOCK:20,SHIFT:16,CONTROL:17,ALT:18,META:91,LEFTBACKSLASH:226,ESCAPE:27,HOME:36,END:35,PAGEUP:33,PAGEDOWN:34,DELETE:46,INSERT:45,PAUSE:19,UP:38,DOWN:40,LEFT:37,RIGHT:39,CONTEXT:93,SPACE:32,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123};
-var keyPress = [];
-var keyDown = [];
-var mousePress = [];
-var mouseDown = [];
-var scroll = 0;
-var mousePos = {
-    x:0,
-    y:0
-}
-var preventedEvents = [false,true,true];
-
-function addListenersTo(elementToListenTo) {
-    window.addEventListener("keydown",kdown);
-    window.addEventListener("keyup",kup);
-    elementToListenTo.addEventListener("mousedown",mdown);
-    elementToListenTo.addEventListener("mouseup",mup);
-    elementToListenTo.addEventListener("mousemove",mmove);
-    elementToListenTo.addEventListener("contextmenu",cmenu);
-    elementToListenTo.addEventListener("wheel",scrl);
-}
-function removeListenersFrom(elementToListenTo) {
-    window.removeEventListener("keydown",kdown);
-    window.removeEventListener("keyup",kup);
-    elementToListenTo.removeEventListener("mousedown",mdown);
-    elementToListenTo.removeEventListener("mouseup",mup);
-    elementToListenTo.removeEventListener("mousemove",mmove);
-    elementToListenTo.removeEventListener("contextmenu",cmenu);
-    elementToListenTo.removeEventListener("wheel",scrl);
-}
-function resetInput() {
-    for(var i=0;i<keyPress.length;i++){if(keyPress[i]){keyPress[i]=0}}
-    for(var i=0;i<mousePress.length;i++){if(mousePress[i]){mousePress[i]=0}}
-    scroll=0;
-}
-function kdown(e) {
-    var h=e.keyCode;
-    keyPress[h]=keyPress[h]==[][[]]?1:0;
-    keyDown[h]=1;
-    if(preventedEvents[0]) {e.preventDefault()}
-}
-function kup(e) {
-    var h=e.keyCode;
-    delete keyPress[h];
-    delete keyDown[h];
-}
-function mdown(e) {
-    var h=e.button;
-    mousePress[h]=mousePress[h]==[][[]]?1:0;
-    mouseDown[h]=1;
-    if(preventedEvents[1]) {e.preventDefault()}
-}
-function mup(e) {
-    var h=e.button;
-    delete mousePress[h];
-    delete mouseDown[h];
-}
-function mmove(e) {
-    mousePos.x=e.offsetX/(!canvasScale?autoScale:canvasScale);
-    mousePos.y=e.offsetY/(!canvasScale?autoScale:canvasScale);    
-}
-function cmenu(e) {
-    if(preventedEvents[1]) {e.preventDefault()}
-}
-function scrl(e) {
-    scroll+=-1*(e.deltaY/100);
-    if(preventedEvents[2]) {e.preventDefault()}
-}
-function dist(point1,point2) {
-    let one = (point2.x - point1.x);
-    let two = (point2.y - point1.y);
-    return Math.sqrt((one*one)+(two*two));
-}
-
-function circlecircle(circle1,circle2) {
-    if( dist(circle1,circle2) < (circle1.r + circle2.r)) {
-		return true;
-	} else {
-        return false;
-    }
-}
-
-function circlepoint(circle,point) {
-    if( dist(circle,point) < circle.r) {
-		return true;
-	} else {
-        return false;
-    }
-}
-
-function rectrect(rect1,rect2) {
-    if(rect1.x + rect1.w/2 >= rect2.x - rect2.w/2 &&
-       rect1.x - rect1.w/2 <= rect2.x + rect2.w/2 &&
-       rect1.y + rect1.h/2 >= rect2.y - rect2.h/2 &&
-       rect1.y - rect1.h/2 <= rect2.y + rect2.h/2) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-function rectpoint(rect,point) {
-    if(rect.x + rect.w/2 >= point.x &&
-       rect.x - rect.w/2 <= point.x &&
-       rect.y + rect.h/2 >= point.y &&
-       rect.y - rect.h/2 <= point.y ) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-function circlerect(circle,rect) { //credit: https://yal.cc/rectangle-circle-intersection-test/
-    let rectHalfWidth  = rect.w/2;
-    let rectHalfHeight = rect.h/2;
-    let deltaX = circle.x - Math.max(rect.x - rectHalfWidth, Math.min(circle.x, rect.x + rectHalfWidth));
-    let deltaY = circle.y - Math.max(rect.y - rectHalfHeight, Math.min(circle.y, rect.y + rectHalfHeight));
-    return (deltaX * deltaX + deltaY * deltaY) < (circle.r * circle.r);
-}
-
-function circleOnSideRect(circle,rect) {
-    let rectHalfWidth  = rect.w/2;
-    let rectHalfHeight = rect.h/2;
-    let left   = rect.x - rectHalfWidth;
-    let right  = rect.x + rectHalfWidth;
-    let top    = rect.y - rectHalfHeight;
-    let bottom = rect.y + rectHalfHeight;
-    let cx = circle.x;
-    let cy = circle.y;
-    if(cy < top && cx > left && cx < right) { // top side
-        return 0;
-    } else if(cy > bottom && cx > left && cx < right) { // bottom side
-        return 2;
-    } else if (cx < left && cy > top && cy < bottom) { // left side
-        return 3;
-    } else if (cx > right && cy > top && cy < bottom) { // right side
-        return 1;
-    } else {
-        let returnValue=0; // 0 = top, 1 = right, 2 = bottom, 3 = left
-        let topleft = dist (circle,{x:left,y:top});
-        let topright = dist (circle,{x:right,y:top});
-        let bottomleft = dist (circle,{x:left,y:bottom});
-        let bottomright = dist (circle,{x:right,y:bottom});
-        switch(Math.min(topleft,topright,bottomleft,bottomright)) { // find what corner the cricle is closer to, then determine what side it is closer to
-            case topleft:
-                var m = slope(rect,{x:left,y:top});
-                var mperp = -(1/m);
-                var b = yIntercept(rect,m);
-                var bperp = yIntercept(circle,mperp);
-                var mid = POI(m,b,mperp,bperp);
-                if(cx<mid) {returnValue = 3;} else {returnValue = 0;}
-                break;
-            case topright:
-                var m = slope(rect,{x:right,y:top});
-                var mperp = -(1/m);
-                var b = yIntercept(rect,m);
-                var bperp = yIntercept(circle,mperp);
-                var mid = POI(m,b,mperp,bperp);
-                if(cx<mid) {returnValue = 0;} else {returnValue = 1;}
-                break;
-            case bottomleft:
-                var m = slope(rect,{x:left,y:bottom});
-                var mperp = -(1/m);
-                var b = yIntercept(rect,m);
-                var bperp = yIntercept(circle,mperp);
-                var mid = POI(m,b,mperp,bperp);
-                if(cx<mid) {returnValue = 3;} else {returnValue = 2;}
-                break;
-            case bottomright:
-                var m = slope(rect,{x:right,y:bottom});
-                var mperp = -(1/m);
-                var b = yIntercept(rect,m);
-                var bperp = yIntercept(circle,mperp);
-                var mid = POI(m,b,mperp,bperp);
-                if(cx<mid) {returnValue = 2;} else {returnValue = 1;}
-                break;
-        }
-        return returnValue;
-    }
-}
-
-function rectOnSideRect(rect1,rect2) {
-    let rectHalfWidth2  = rect2.w/2;
-    let rectHalfHeight2 = rect2.h/2;
-    let left2   = rect2.x - rectHalfWidth2;
-    let right2 = rect2.x + rectHalfWidth2;
-    let top2   = rect2.y - rectHalfHeight2;
-    let bottom2 = rect2.y + rectHalfHeight2;
-
-    let rectHalfWidth1  = rect1.w/2;
-    let rectHalfHeight1 = rect1.h/2;
-    let rx1 = rect1.x;
-    let ry1 = rect1.y;
-    let left1   = rx1 - rectHalfWidth1;
-    let right1 = rx1 + rectHalfWidth1;
-    let top1   = ry1 - rectHalfHeight1;
-    let bottom1 = ry1 + rectHalfHeight1;
-    // find what point is closer to the rectangle 
-    let topleft1 = dist (rect2,{x:left1,y:top1});
-    let topright1 = dist (rect2,{x:right1,y:top1});
-    let bottomleft1 = dist (rect2,{x:left1,y:bottom1});
-    let bottomright1 = dist (rect2,{x:right1,y:bottom1});
-    let topmiddle1 = dist (rect2,{x:rx1,y:top1});
-    let rightmiddle1 = dist (rect2,{x:right1,y:ry1});
-    let bottommiddle1 = dist (rect2,{x:rx1,y:bottom1});
-    let leftmiddle1 = dist (rect2,{x:left1,y:ry1});
-    let cx = rx1;
-    let cy = ry1;
-    switch(Math.min(topleft1,topright1,bottomleft1,bottomright1,topmiddle1,rightmiddle1,bottommiddle1,leftmiddle1)) {
-        //set the point we are testing to the closest point to the rectangle
-        case topleft1:
-            cx -= rect1.w/2;
-            cy -= rect1.h/2;
-            break;
-        case topright1:
-            cx += rect1.w/2;
-            cy -= rect1.h/2;
-            break;
-        case bottomleft1:
-            cx -= rect1.w/2;
-            cy += rect1.h/2;
-            break;
-        case bottomright1:
-            cx += rect1.w/2;
-            cy += rect1.h/2;
-            break;
-        case topmiddle1:
-            cy -= rect1.h/2;
-            break;
-        case rightmiddle1:
-            cx += rect1.w/2;
-            break;
-        case bottommiddle1:
-            cy += rect1.h/2;
-            break;
-        case leftmiddle1:
-            cx -= rect1.w/2;
-            break;
-    }
-    if(cy < top2 && cx > left2 && cx < right2) { // top side
-        return 0;
-    } else if(cy > bottom2 && cx > left2 && cx < right2) { // bottom side
-        return 2;
-    } else if (cx < left2 && cy > top2 && cy < bottom2) { // left side
-        return 3;
-    } else if (cx > right2 && cy > top2 && cy < bottom2) { // right side
-        return 1;
-    } else {
-        let returnValue=0; // 0 = top, 1 = right, 2 = bottom, 3 = left
-        let determiningPoint = {x:cx,y:cy};
-        let topleft = dist (determiningPoint,{x:left2,y:top2});
-        let topright = dist (determiningPoint,{x:right2,y:top2});
-        let bottomleft = dist (determiningPoint,{x:left2,y:bottom2});
-        let bottomright = dist (determiningPoint,{x:right2,y:bottom2});
-        switch(Math.min(topleft,topright,bottomleft,bottomright)) { // find what corner the point is closer to, then determine what side it is closer to
-            case topleft:
-                var m = slope(rect2,{x:left2,y:top2});
-                var mperp = -(1/m);
-                var b = yIntercept(rect2,m);
-                var bperp = yIntercept(determiningPoint,mperp);
-                var mid = POI(m,b,mperp,bperp);
-                if(cx<mid) {returnValue = 3;} else {returnValue = 0;}
-                break;
-            case topright:
-                var m = slope(rect2,{x:right2,y:top2});
-                var mperp = -(1/m);
-                var b = yIntercept(rect2,m);
-                var bperp = yIntercept(determiningPoint,mperp);
-                var mid = POI(m,b,mperp,bperp);
-                if(cx<mid) {returnValue = 0;} else {returnValue = 1;}
-                break;
-            case bottomleft:
-                var m = slope(rect2,{x:left2,y:bottom2});
-                var mperp = -(1/m);
-                var b = yIntercept(rect2,m);
-                var bperp = yIntercept(determiningPoint,mperp);
-                var mid = POI(m,b,mperp,bperp);
-                if(cx<mid) {returnValue = 3;} else {returnValue = 2;}
-                break;
-            case bottomright:
-                var m = slope(rect2,{x:right2,y:bottom2});
-                var mperp = -(1/m);
-                var b = yIntercept(rect2,m);
-                var bperp = yIntercept(determiningPoint,mperp);
-                var mid = POI(m,b,mperp,bperp);
-                if(cx<mid) {returnValue = 2;} else {returnValue = 1;}
-                break;
-        }
-        return returnValue;
-    }
-}
-
-function slope(point1,point2) {
-    return ((point2.y-point1.y)/(point2.x-point1.x));
-}
-
-function yIntercept(point,slope) {
-    return point.y - (slope * point.x);
-}
-
-function POI(m1,b1,m2,b2) {
-    x = (b2 - b1) / (m1 - m2);
-    return x;
-    //y = m1 * x + b1;
-}
-
-function ifRectOnEdgeBounce(rect) {
-    let rx = rect.x;
-    let ry = rect.y;
-    let rw = rect.w/2;
-    let rh = rect.h/2;
-    if(rx+rw>edge.right) {
-        rect.v.x *= -1;
-        rect.x = edge.right-rw;
-    }
-    if(rx-rw<edge.left) {
-        rect.v.x *= -1;
-        rect.x = edge.left+rw;
-    }
-    if(ry+rh>edge.bottom) {
-        rect.v.y *= -1;
-        rect.y = edge.bottom-rh;
-    }
-    if(ry-rh<edge.top) {
-        rect.v.y *= -1;
-        rect.y = edge.top+rh;
-    }
-}
-
-function ifCircleOnEdgeBounce(circle) {
-    let cx = circle.x;
-    let cy = circle.y;
-    let cr = circle.r;
-    if(cx+cr>edge.right) {
-        circle.v.x *= -1;
-        circle.x = edge.right-cr;
-    }
-    if(cx-cr<edge.left) {
-        circle.v.x *= -1;
-        circle.x = edge.left+cr;
-    }
-    if(cy+cr>edge.bottom) {
-        circle.v.y *= -1;
-        circle.y = edge.bottom-cr;
-    }
-    if(cy-cr<edge.top) {
-        circle.v.y *= -1;
-        circle.y = edge.top+cr;
-    }
-}
-// create globals
-var canvases={cvs:null,ctx:null,buffer1cvs:null,buffer1ctx:null,buffer2cvs:null,buffer2ctx:null}, // visable and hidden canvases
-cw, // canvas width
-ch, // canvas height
-camera={zoom:1,angle:0,x:0,y:0}, // affects how everything is drawn
-updateFPS=60,
-gameStarted=false,
-drawMode=0, // 0=normal, 1=zoomed, 2=zoomed/rotated, set automatically depending on camera
-absDraw=false,
-curCtx, // what canvas to draw to
-maxCvsSize, // used by second buffer
-canvasScale=1,
-difx=0, // offsets for drawing
-dify=0,
-seperateInputLoop=true,
-edge={top:null,bottom:null,left:null,right:null}, // used by if___OnEdgeBounce, set to canvas size at setup, can be changed whenever
-drawLimitLeft,
-drawLimitRight,
-drawLimitTop,
-drawLimitBottom,
-sizeDif,
-bug="\uD83D\uDC1B",
-loadingCircle,
-loadAng=0,
-optionsHover=0,
-pauseHover=0,
-optionsMenu=false,
-optionsButtons={},
-clickSound,
-paused=false,
-screenSize="1:1",
-autoScale=1,
-
-images=[], // put image paths here
-imagePaths=[],
-imgs=[],
-sprites={}, // loaded images
-
-audio=[], // put audio paths here
-audioPaths=[],
-sounds={}, // loaded sounds
-abuffer = [], // audio nodes shoved here
-volumeList = [], // gain nodes shoved here
-audioLoadedLength=0,
-volume={sfx:1,bgm:1};
-/* options
-    future:
-        modefileable checklist
-        key bindings
-*/
-
-cursor = {sprite:null,alignment:1,show:true}, // 0=topleft, 1=centered
-mouseOnCanvas=false;
-
-const acceptableChars="qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890_-. ";//for image names
-
-const AudioContext = window.AudioContext||window.webkitAudioContext;
-var context;
-var sfxVolumeNode;
-var bmgVolumeNode;
-
-document.getElementById("game").onmouseout = function()   {mouseOnCanvas = false;}
-document.getElementById("game").onmouseover = function()   {mouseOnCanvas = true;}
-
-//setup canvases and input
-function setup(physicsFPS) {
-    updateFPS = physicsFPS;
-    
-    canvases.cvs = document.getElementById("game");
-    canvases.ctx = canvases.cvs.getContext("2d", { alpha: false });
-
-    canvases.cvs.onmousedown = function () {if(!gameStarted){loadImagesAndSounds();gameStarted=true;}}
-
-    createCanvas("buffer1");
-    createCanvas("buffer2");
-
-    canvases.ctx.imageSmoothingEnabled = false;
-    canvases.buffer1ctx.imageSmoothingEnabled = false;
-    canvases.buffer2ctx.imageSmoothingEnabled = false;
-
-    maxCvsSize=Math.max(canvases.cvs.width,canvases.cvs.height);
-    sizeDif=maxCvsSize-Math.min(canvases.cvs.width,canvases.cvs.height);
-    cw=canvases.cvs.width;
-    ch=canvases.cvs.height;
-    
-    edge={top:0,bottom:ch,left:0,right:cw};
-
-    addFont();
-    addStyle();
-
-    addListenersTo(canvases.cvs);
-
-    curCtx = canvases.ctx;
-    requestAnimationFrame(startButton);
-    function startButton() {
-        curCtx.fillStyle="#2d2d2d";
-        curCtx.fillRect(0,0,cw,ch);//debugger;
-        circle(cw/2,ch/2,27,"#066312");
-        circle(cw/2,ch/2,23,"#149124");
-        shape(cw/2,ch/2,[{x:-7,y:-15},{x:-7,y:15},{x:15,y:0}],"#47f55d");
-        if(!gameStarted) {requestAnimationFrame(startButton);}
-    }
-}
-
-function drawLoop() {
-    cw=canvases.cvs.width;
-    ch=canvases.cvs.height;
-    scaleCanvases();
-
-    switchDrawMode();
-    
-    resizeBuffers();
-
-    clearCanvases();
-
-    var limitModifyer = 0;
-    if(drawMode==2) {limitModifyer=canvases.buffer2cvs.width-maxCvsSize;}
-    drawLimitLeft   = -camera.x - (drawMode==2?sizeDif:0) - limitModifyer;
-    drawLimitRight  = -camera.x + maxCvsSize + (drawMode==2?sizeDif:0) + limitModifyer;
-    drawLimitTop    = -camera.y -(drawMode==2?sizeDif:0) - limitModifyer;
-    drawLimitBottom = -camera.y + maxCvsSize + (drawMode==2?sizeDif:0) + limitModifyer;
-
-    draw();
-    
-    render();
-
-    curCtx=canvases.ctx;
-    difx=0;dify=0;
-    var camCache = {x:camera.x,y:camera.y};
-    var drawModeCache = drawMode;
-    camera.x=0;camera.y=0;
-    drawMode=0;
-    absDraw=true;
-    absoluteDraw();
-    absDraw=false;
-
-    drawButtons();
-    drawOptionsMenu();
-    drawCursor();
-
-    drawMode=drawModeCache;
-
-    camera.x = camCache.x;
-    camera.y = camCache.y;
-
-    requestAnimationFrame(drawLoop);
-}
-
-function updateLoop() {
-    if(seperateInputLoop==false) {
-        handleOptionsInput();
-    }
-    sfxVolumeNode.gain.value = volume.sfx;
-    bmgVolumeNode.gain.value = volume.bgm;
-    if(!paused) {
-        update();
-    }
-
-    if(seperateInputLoop==false) {
-        resetInput();
-    }
-}
-
-
-function inputLoop() {
-    handleOptionsInput();
-    if(!paused) {
-        input();
-    }
-
-    resetInput();
+function createCanvas(id) {
+    var tempCanvas = document.createElement("canvas");
+    tempCanvas.id = id;
+    tempCanvas.width = canvases.cvs.width;
+    tempCanvas.height = canvases.cvs.height;
+    tempCanvas.style = "image-rendering:pixelated;image-rendering: crisp-edges;display:none";//display:none;
+
+    document.body.appendChild(tempCanvas);
+
+    canvases[`${id}cvs`] = document.getElementById(id);
+    canvases[`${id}ctx`] = canvases[`${id}cvs`].getContext("2d");
+}
+
+function startLoops() {
+    try {draw} catch (err){console.warn(bug+" no draw function found");return null;}
+    try {update} catch (err){console.warn(bug+" no update function found");return null;}
+    try {input} catch (err){seperateInputLoop=false;}
+    onAssetsLoaded();
+
+    requestAnimationFrame(drawLoop);
+    setInterval(updateLoop,1000/updateFPS);
+
+    if(seperateInputLoop) {
+        setInterval(inputLoop,4);
+    }
+}
+
+function mousePosition() {
+    if(drawMode===0) {
+        return {x:(mousePos.x)-camera.x,y:(mousePos.y)-camera.y};
+    } else if(drawMode===1) {
+        var xoff = canvases.cvs.width/2;
+        var yoff = canvases.cvs.height/2;
+        return {x:((mousePos.x-xoff)/camera.zoom+xoff)-camera.x,y:((mousePos.y-yoff)/camera.zoom+yoff)-camera.y};
+    } else {
+        var xoff = canvases.cvs.width/2;
+        var yoff = canvases.cvs.height/2;
+        var tempPos = {x:((mousePos.x-xoff)/camera.zoom+xoff)-camera.x,y:((mousePos.y-yoff)/camera.zoom+yoff)-camera.y};
+
+        var center = {x:-camera.x + cw/2, y:-camera.y + ch/2};
+        var tempAngle = pointTo(center,tempPos) - camera.angle; 
+        var tempDist = dist(center,tempPos);
+
+        return {x:center.x + (Math.cos(tempAngle) * tempDist),y:center.y + (Math.sin(tempAngle) * tempDist)}
+    }
+}
+
+function addStyle() {
+    var tempStyle = document.createElement("style");
+    tempStyle.id="gamejsstyle";
+    document.head.appendChild(tempStyle);
+    var tempMeta = document.createElement("meta");
+    tempMeta.setAttribute("charset","utf-8");
+    document.head.appendChild(tempMeta);
+}
+
+function rand(min,max) {
+    return Math.floor(Math.random() * (max - min + 1)) + min;
+}
+
+function radToDeg(rad) {return rad / Math.PI * 180;}
+function degToRad(deg) {return deg * Math.PI / 180;}
+
+function velocity(angle) {
+    return {x:Math.sin(angle),y:Math.cos(angle)};
+}
+
+function pointTo(point,targetPoint) {
+    var adjacent = (targetPoint.x - point.x);
+    var opposite = (targetPoint.y - point.y);
+    var h = Math.atan2(opposite, adjacent);
+    return h;
+}
+
+function loadImagesAndSounds() {
+    var curpath="";
+    context = new AudioContext();
+    sfxVolumeNode = context.createGain();
+    sfxVolumeNode.connect(context.destination);
+    bmgVolumeNode = context.createGain();
+    bmgVolumeNode.connect(context.destination);
+    deeper(images,"image");
+    deeper(audio,"sound");
+    function deeper(curpos,type) {
+        let addedPath="";
+        for(let j=0;j<curpos.length;j++) {
+            if(typeof curpos[j]=="string") {
+                if(j==0) {
+                    curpath+=curpos[j];
+                    addedPath = curpos[j];
+                } else {
+                    if(type=="image") {
+                        let name = curpath + curpos[j];
+                        imagePaths.push(name);
+                        let temp = new Image();
+                        temp.src = name;
+                        temp.onerror = function () {
+                            console.warn(bug+" "+this.src + " was not found");
+                        };
+                        temp.onload = function() {spriteLoad(name,temp);}
+                        imgs.push(temp);
+                    } else if(type=="sound") {
+                        audioPaths.push(curpath + curpos[j]);
+                        newSound(curpath + curpos[j]);
+                    }
+                }
+            }
+            if(typeof curpos[j]=="object") {
+               deeper(curpos[j],type);
+            }
+        }
+        curpath = curpath.slice(0,curpath.length-addedPath.length);
+    }
+    
+    loadingCircle = new Image();
+    loadingCircle.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAf0lEQVQ4jc2SuxHAIAxDbY4pMpHmyJSeKGuQKpyj2Hy6qETPQvhQCWRmDRfeZ4cJAGW28mAUyL4Pqmx2nfK+zaR59glRHo5qZi0BaPHmbDhiyuzdsza9wcrtEVtG4Ip+FLCzTM+WneWxPv9gpQUzmhncLPOHUCYfHr4/C4r2dQPfhkeIbjeYWgAAAABJRU5ErkJggg==";
+    clickSound = new Audio("data:audio/x-wav;base64,UklGRowBAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YWgBAADa/6T/2/+S/x//pP769Xr4fPh5+H34evh7+Pv6gf18/QIAhQcIDxUZFR4VHhgeEx6TFgkPCgqAAnz49/X18HLu7ubo4eXc5dzj3Gjf5+Fr5G7pce759YECiwwRFBQZlxuXG5cbFRmTFo8RCAoAAPz69/X08G7udO5s7vz1dvj++nv9gP3+/wEAgwKBAogHkBEpLUNG1lzqcPV683r4eu51ZmnVV7w+qypy88fDoKAXlAqKBoUAgIeHlpYsrTu87Ot9/ZIRGxkoKDEtqionIxgZiwfj5lnaz9JN0E3QV9pd3+Tm9fUBAAQFBwWNDBEPFxSYFpsWEA9+/fP1dfNt83bz8fX9+gQFkAwPDxQPEQ+IBwIAdfjv8OLm2+HX3Nrh4+bm63n4BAUUDx0ZqyCrJSkelBGEAnb4a+5a5Njcztxc31jkZunx9QgFGhQfGa0gqCCuIKkgpRsaFIsHdfhj6dfh0NzM19Th6es=");
+    let pos = {x:cw/2-100,y:ch/2-100};
+    optionsButtons.screenSize = {x:pos.x+160,y:pos.y+12,w:50,h:20};
+    optionsButtons.sfx = {x:pos.x+125,y:pos.y+40,w:120,h:20};
+    optionsButtons.bmg = {x:pos.x+125,y:pos.y+70,w:120,h:20};
+    loadLoop();
+}
+
+function loadLoop() {
+    if(Object.keys(sprites).length == imagePaths.length && audioPaths.length == audioLoadedLength) {
+        startLoops();
+        imagePaths=[];
+        audioPaths=[];
+        imgs=[];
+    } else {
+        curCtx.fillStyle="#2d2d2d";
+        curCtx.fillRect(0,0,cw,ch);
+        text(`audio:   ${audioLoadedLength}/${audioPaths.length}`,10,30,"white",2);
+        text(`sprites: ${Object.keys(sprites).length}/${imagePaths.length}`,10,10,"white",2);
+        curCtx.setTransform(1, 0, 0, 1, Math.round(cw/2), Math.round(ch/2));
+        curCtx.rotate(loadAng);
+        loadAng+=0.1;
+        curCtx.drawImage(loadingCircle,Math.round(-8),Math.round(-8));
+        curCtx.setTransform(1, 0, 0, 1, 0, 0);
+        requestAnimationFrame(loadLoop);
+    }
+}
+
+function spriteLoad(path,image) {
+    let startpos;
+    let endpos = path.lastIndexOf(".");
+    for(let j=endpos-1;acceptableChars.includes(path[j]);j--) {startpos=j;}
+    let spriteName = path.slice(startpos,endpos)
+    let dsize=Math.max(image.width,image.height)/2;
+    sprites[spriteName] = {spr:image,drawLimitSize:dsize};
+    
+}
+
+function newSound(src) {
+    let startpos;
+    let endpos = src.lastIndexOf(".");
+    for(let j=endpos-1;acceptableChars.includes(src[j]);j--) {startpos=j;}
+    let soundName = src.slice(startpos,endpos); 
+    sounds[soundName] = {nodes:[],volNodes:[],src:src,type:"sfx",volume:1};
+    sounds[soundName].nodes = [1];
+
+    let loadingSound = new Audio();
+    loadingSound.onerror = function () {
+        console.warn(bug+" "+ src + " was not found");
+    };
+    loadingSound.src = src;
+    loadingSound.preload='auto';
+    loadingSound.addEventListener('canplaythrough', function() { 
+        audioLoadedLength++;
+     }, false);
+    sounds[soundName].nodes.push(loadingSound);
+
+    let soundNode = context.createMediaElementSource(loadingSound);
+    let gainNode = context.createGain();
+
+    soundNode.connect(gainNode);
+    gainNode.connect(sfxVolumeNode);
+
+    abuffer.push(soundNode);
+    volumeList.push(gainNode);
+    sounds[soundName].volNodes.push(volumeList.length-1);
+}
+
+function addSound(sound) {
+    let loadingSound = new Audio();
+    loadingSound.src = sound.src;
+    loadingSound.preload='auto';
+    sound.nodes.splice(sound.nodes[0],0,loadingSound);
+
+    let soundNode = context.createMediaElementSource(loadingSound);
+    let gainNode = context.createGain();
+    gainNode.gain.value=sound.volume;
+
+    soundNode.connect(gainNode);
+    gainNode.connect(sound.type=="sfx"?sfxVolumeNode:bmgVolumeNode);
+
+    abuffer.push(soundNode);
+    volumeList.push(gainNode);
+    sound.volNodes.push(volumeList.length-1);
+
+    volumeList[sound.volNodes[sound.volNodes.length-1]].gain.value = volumeList[sound.volNodes[0]].gain.value
+}
+
+
+
+function play(sound) {
+    s=sound.nodes;
+    if(s[s[0]].ended || !(s[s[0]].played.length)) {
+        s[s[0]].play();
+        s[0]++;
+        if(s[0]==s.length) {
+            s[0]=1;
+        }
+    } else {
+        addSound(sound);
+        s[s[0]].play();
+        s[0]++;
+        if(s[0]==s.length) {
+            s[0]=1;
+        }
+    }
+}
+
+function setVolume(sound,volume) {
+    for(let i=0,l=sound.volNodes.length;i<l;i++) {
+        volumeList[sound.volNodes[i]].gain.value = volume;
+    }
+}
+
+function setType(sound,newType) {
+    for(let i=0,l=sound.volNodes.length;i<l;i++) {
+        volumeList[sound.volNodes[i]].disconnect(sound.type=="sfx"?sfxVolumeNode:bmgVolumeNode);
+        volumeList[sound.volNodes[i]].connect(newType=="sfx"?sfxVolumeNode:bmgVolumeNode);
+    }
+    sound.type = newType;
+}
+
+function stop(sound) {
+    s=sound.nodes;
+    for(let i=1;i<s.length;i++) {
+        s[i].pause();
+        s[i].currentTime = 0;
+    }
+}
+
+function handleOptionsInput() {
+    let ImTierdMakemenuwork=true;
+    if(optionsMenu) {
+        if(mousePress[0]) {
+            if(rectpoint(optionsButtons.screenSize,mousePos)) {
+                if(screenSize=="1:1") {
+                    screenSize = "fit";
+                    canvasScale=0;
+                } else {
+                    screenSize = "1:1";
+                    canvasScale=1;
+                }
+            }
+            if(!rectpoint({x:cw/2,y:ch/2,w:200,h:200},mousePos)) {
+                optionsMenu=false;
+                ImTierdMakemenuwork=false;
+            }
+        }
+        if(mouseDown[0]) {
+            if(rectpoint(optionsButtons.sfx,mousePos)) {
+                volume.sfx = (mousePos.x-(optionsButtons.sfx.x-60))/120;
+            }
+            if(rectpoint(optionsButtons.bmg,mousePos)) {
+                volume.bgm = (mousePos.x-(optionsButtons.bmg.x-60))/120;
+            }
+        }
+    }
+    if(mousePos.x>cw-32&&mousePos.y<32) {
+        if(mousePress[0]&&ImTierdMakemenuwork) {
+            clickSound.play();
+            paused=true;
+            optionsMenu=!optionsMenu;
+        }
+        optionsHover = 25;
+    } else {
+        optionsHover = 0;
+    }
+    if(mousePos.x<cw-32&&mousePos.x>cw-64&&mousePos.y<32) {
+        pauseHover = 25;
+        if(mousePress[0]) {
+            clickSound.play();
+            paused=!paused;
+        }
+    } else {
+        pauseHover = 0;
+    }
+    
+}
+function addFont() {
+    var tempStyle = document.createElement("style");
+    tempStyle.innerHTML = `
+    @font-face {
+        font-family: 'PixelArial11';
+        src: url("./pixelmix.ttf") format('truetype');
+        font-weight: 900;
+        font-style: normal;
+    
+    }
+    html {font-family: 'PixelArial11' !important; font-size: 16px;}
+    `;
+    document.head.appendChild(tempStyle);
+    canvases.ctx.textBaseline = "hanging";
+    canvases.ctx.textAlign = "left";
+}
+var scaleDefault = 1;
+function img(img,x,y,angle=0,sx=scaleDefault,sy=scaleDefault) {
+    var half = img.drawLimitSize;
+    if((x+half>drawLimitLeft&&x-half<drawLimitRight&&y+half>drawLimitTop&&y-half<drawLimitBottom)||absDraw) {
+        let spr = img.spr;
+        if(angle===0&&sx===1&&sy===1) {
+            curCtx.drawImage(spr,Math.round(x+camera.x+difx-(spr.width/2)),Math.round(y+camera.y+dify-(spr.height/2)));
+        } else {
+            curCtx.setTransform(sx, 0, 0, sy, Math.round(x+camera.x+difx), Math.round(y+camera.y+dify));
+            curCtx.rotate(angle);
+            curCtx.drawImage(spr,Math.round(-spr.width/2),Math.round(-spr.height/2));
+            curCtx.setTransform(1, 0, 0, 1, 0, 0);
+        }
+    }
+}
+
+function imgIgnoreCutoff(img,x,y,angle=0,sx=1,sy=1) {
+    let spr = img.spr;
+    if(angle===0&&sx===1&&sy===1) {
+        curCtx.drawImage(spr,Math.round(x+camera.x+difx-(spr.width/2)),Math.round(y+camera.y+dify-(spr.height/2)));
+    } else {
+        curCtx.setTransform(sx, 0, 0, sy, Math.round(x+camera.x+difx), Math.round(y+camera.y+dify));
+        curCtx.rotate(angle);
+        curCtx.drawImage(spr,Math.round(-spr.width/2),Math.round(-spr.height/2));
+        curCtx.setTransform(1, 0, 0, 1, 0, 0);
+    }
+}
+
+function rect(x,y,w,h,color) {
+    curCtx.fillStyle = color;
+    curCtx.fillRect(x-(w/2)+camera.x+difx,y-(h/2)+camera.y+dify,w,h);
+}
+
+function circle(x,y,r,color) {
+    curCtx.beginPath();
+    curCtx.arc(x+camera.x+difx, y+camera.y+dify, r, 0, 2 * Math.PI, false);
+    curCtx.fillStyle = color;
+    curCtx.fill();
+}
+
+function shape(x,y,relitivePoints,color) {
+    x+=camera.x+difx;
+    y+=camera.y+dify;
+    curCtx.fillStyle = color;
+    curCtx.beginPath();
+    curCtx.moveTo(x+relitivePoints[0].x, y+relitivePoints[0].y);
+    for(let i=1,l=relitivePoints.length;i<l;i++) {
+        curCtx.lineTo(x+relitivePoints[i].x, y+relitivePoints[i].y);
+    }
+    curCtx.fill();
+}
+
+function text(txt,x,y,color="black",size=1,maxWidth=cw) {
+    txt = txt.toString();
+    curCtx.fillStyle = color;
+    curCtx.font = `${Math.round(size)*8}px PixelArial11`;
+                                                                                        //I hate text wrapping now 
+    var txtList = txt.split("\n");                                                      //split string on enters
+    for(let i=0;i<txtList.length;i++) {                                                 //go through array of strings
+        if(curCtx.measureText(txtList[i]).width>maxWidth) {                             //if the string is too big, divide up into smaller strings
+            var tempTxt = txtList[i].split(" ");                                        //split into individual words
+            var tempStr="";                                                             //string for measuring size
+            var addAmount=0;                                                            //track where in the txtList we are
+            txtList.splice(i,1);                                                        //remove the too long string
+            for(let j=0;j<tempTxt.length;j++) {                                         //go through the split up string
+                if(curCtx.measureText(tempStr + tempTxt[j] + " ").width<maxWidth) {     //if adding a word doesn't make tempStr too long, add it, other wise, add tempStr to txtList;
+                    tempStr += tempTxt[j] + " ";
+                } else {
+                    if(j==0) {tempStr+=tempTxt[j];}                                     //if we are here when j is 0, we have one word that is longer then the maxWidth, so we just draw it
+                    txtList.splice(i+addAmount,0,tempStr);                              //put tempStr in txtList
+                    addAmount++;                                                        //move the position we put the tempStr in
+                    tempStr="";                                                         //reset tempStr
+                    tempTxt.splice(0,(j==0?1:j));                                       //delete words that have been used
+                    j=-1;                                                               //make it so in the next loop, j starts at 0
+                }
+            }
+            if(tempStr.length!=0) {
+                txtList.splice(i+addAmount,0,tempStr);                                  //add any leftover text
+            }
+        }
+    }
+
+    for(let i=0;i<txtList.length;i++) {
+        curCtx.fillText(txtList[i],x+camera.x+difx,y+camera.y+dify+((i+(drawMode?1:0))*8*size+(size*i)));
+    }
+}
+
+function textWidth(txt,size=1) {
+    txt = txt.toString();
+    curCtx.font = `${Math.round(size)*8}px PixelArial11`;
+    return curCtx.measureText(txt).width;
+}
+
+function centerCameraOn(x,y) {
+    camera.x = -x+canvases.cvs.width/2;
+    camera.y = -y+canvases.cvs.height/2;
+}
+
+function moveCamera(x,y) {
+    camera.x -= y * Math.sin(camera.angle);
+    camera.y -= y * Math.cos(camera.angle);
+    camera.x -= x * Math.sin(camera.angle + 1.57079632);
+    camera.y -= x * Math.cos(camera.angle + 1.57079632);
+}
+
+function imgRotScale(x,y,angle,scale,pic,ctx) { //used for camera movement
+    ctx.setTransform(scale, 0, 0, scale, x, y);
+    ctx.rotate(angle);
+    ctx.drawImage(pic,-pic.width/2,-pic.height/2);
+    ctx.setTransform(1, 0, 0, 1, 0, 0);
+}
+
+function drawCursor() {
+    if(cursor.sprite&&mouseOnCanvas) {
+        if(cursor.alignment) {
+            canvases.ctx.drawImage(cursor.sprite.spr,mousePos.x-Math.round(cursor.sprite.spr.width/2),mousePos.y-Math.round(cursor.sprite.spr.height/2));
+        } else {
+            canvases.ctx.drawImage(cursor.sprite.spr,mousePos.x,mousePos.y);
+        }
+        cursor.show = false;
+    } else {
+        cursor.show = true;
+    }
+}
+
+function render() {
+    if(drawMode===1) {
+        imgRotScale(canvases.cvs.width/2,canvases.cvs.height/2,0,camera.zoom,canvases.buffer1cvs,canvases.ctx);
+    }
+    if(drawMode===2) {
+        imgRotScale(canvases.cvs.width/2,canvases.cvs.height/2,camera.angle,1,canvases.buffer2cvs,canvases.buffer1ctx);
+        imgRotScale(canvases.cvs.width/2,canvases.cvs.height/2,0,camera.zoom,canvases.buffer1cvs,canvases.ctx);
+    }
+}
+
+function clearCanvases() {
+    canvases.ctx.clearRect(0,0,canvases.cvs.width,canvases.cvs.height);
+    canvases.buffer1ctx.clearRect(0,0,canvases.buffer1cvs.width,canvases.buffer1cvs.height);
+    canvases.buffer2ctx.clearRect(0,0,canvases.buffer2cvs.width,canvases.buffer2cvs.height);
+}
+
+function switchDrawMode() {
+    if(camera.zoom<1) {camera.zoom=1;}
+    if(camera.angle!=0) {
+        drawMode=2;
+    } else if(camera.zoom!=1) {
+        drawMode=1;
+    } else {
+        drawMode=0;
+    }
+    switch (drawMode) {
+        case 0: curCtx = canvases.ctx; break;
+        case 1: curCtx = canvases.buffer1ctx; break;
+        case 2: curCtx = canvases.buffer2ctx; break;
+    }
+}
+
+function resizeBuffers() {
+    var tempSize = maxCvsSize/camera.zoom;
+    var tempSizeAndPadding = tempSize + (tempSize/2)
+
+    canvases.buffer2cvs.width = tempSizeAndPadding;
+    canvases.buffer2cvs.height = tempSizeAndPadding;
+    
+    if(drawMode===2) {
+        difx = (canvases.buffer2cvs.width - canvases.cvs.width)/2;
+        dify = (canvases.buffer2cvs.height - canvases.cvs.height)/2;
+    } else {
+        difx=0;
+        dify=0;
+    }
+    canvases.buffer2ctx.imageSmoothingEnabled = false;
+}
+
+function scaleCanvases() { //scales canvas by canvas scale, if scale is 0, canvas will try to fit screen
+    var style = document.getElementById("gamejsstyle");
+    if(canvasScale==0) {
+        var tempScale = Math.min(Math.floor(window.innerWidth/canvases.cvs.width),Math.floor(window.innerHeight/canvases.cvs.height));
+        tempScale=tempScale<1?1:tempScale;
+        autoScale=tempScale;
+        style.innerHTML = `#game {image-rendering:pixelated;image-rendering: crisp-edges;width:${tempScale*canvases.cvs.width}px;cursor: ${cursor.show?"crosshair":"none"};}`;
+    } else {
+        style.innerHTML = `#game {image-rendering:pixelated;image-rendering: crisp-edges;width:${Math.floor(canvasScale*canvases.cvs.width)}px;cursor: ${cursor.show?"crosshair":"none"};}`;
+    }
+}
+
+function drawButtons() {
+    let pos = {x:cw-16,y:16}; 
+    //options
+    rect(pos.x,pos.y,34,34,"#9c9c9c");
+    let c = optionsHover+45;
+    rect(pos.x,pos.y,32,32,`rgb(${c},${c},${c})`);
+    c = optionsHover + 69;
+    let cc = `rgb(${c},${c},${c})`;
+    rect(pos.x,pos.y-6,26,4,cc);
+        rect(pos.x-6,pos.y-6,4,8,cc);
+    rect(pos.x,pos.y+6,26,4,cc);
+        rect(pos.x+11,pos.y+6,4,8,cc);
+    //pause
+    pos.x-=33;
+    rect(pos.x,pos.y,34,34,"#9c9c9c");
+    c = pauseHover+45;
+    rect(pos.x,pos.y,32,32,`rgb(${c},${c},${c})`);
+    c = pauseHover + 69;
+    cc = `rgb(${c},${c},${c})`;
+    if(paused) {
+        shape(pos.x,pos.y,[{x:-7,y:-10},{x:-7,y:10},{x:10,y:0}],cc);
+    } else {
+        rect(pos.x+6,pos.y,6,20,cc);
+        rect(pos.x-6,pos.y,6,20,cc);
+    }
+}
+
+function drawOptionsMenu() {
+    if(optionsMenu) {
+        let pos = {x:cw/2-100,y:ch/2-100};
+        rect(cw/2,ch/2,200,200,"#242424");
+        text("Screen Size:",pos.x+2,pos.y+2,"white",2);
+            let b = optionsButtons.screenSize;
+            rect(b.x,b.y,b.w,b.h,"#444444");
+            text(screenSize,pos.x+145,pos.y+4,"white",2);
+        text("sfx",pos.x+2,pos.y+30,"white",2);
+            b = optionsButtons.sfx;
+            rect(b.x,b.y,b.w,b.h-10,"#444444");
+            rect((b.x-60)+(volume.sfx*120),b.y,8,20,"#444444");
+        text("bmg",pos.x+2,pos.y+60,"white",2);
+            b = optionsButtons.bmg;
+            rect(b.x,b.y,b.w,b.h-10,"#444444");
+            rect((b.x-60)+(volume.bgm*120),b.y,8,20,"#444444");
+    }
+}
+var k={a:65,b:66,c:67,d:68,e:69,f:70,g:71,h:72,i:73,j:74,k:75,l:76,m:77,n:78,o:79,p:80,q:81,r:82,s:83,t:84,u:85,v:86,w:87,x:88,y:89,z:90,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,BACKTICK:192,MINUS:189,EQUALS:187,OPENSQUARE:219,ENDSQUARE:221,SEMICOLON:186,SINGLEQUOTE:222,BACKSLASH:220,COMMA:188,PERIOD:190,SLASH:191,ENTER:13,BACKSPACE:8,TAB:9,CAPSLOCK:20,SHIFT:16,CONTROL:17,ALT:18,META:91,LEFTBACKSLASH:226,ESCAPE:27,HOME:36,END:35,PAGEUP:33,PAGEDOWN:34,DELETE:46,INSERT:45,PAUSE:19,UP:38,DOWN:40,LEFT:37,RIGHT:39,CONTEXT:93,SPACE:32,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123};
+var keyPress = [];
+var keyDown = [];
+var mousePress = [];
+var mouseDown = [];
+var scroll = 0;
+var mousePos = {
+    x:0,
+    y:0
+}
+var preventedEvents = [false,true,true];
+
+function addListenersTo(elementToListenTo) {
+    window.addEventListener("keydown",kdown);
+    window.addEventListener("keyup",kup);
+    elementToListenTo.addEventListener("mousedown",mdown);
+    elementToListenTo.addEventListener("mouseup",mup);
+    elementToListenTo.addEventListener("mousemove",mmove);
+    elementToListenTo.addEventListener("contextmenu",cmenu);
+    elementToListenTo.addEventListener("wheel",scrl);
+}
+function removeListenersFrom(elementToListenTo) {
+    window.removeEventListener("keydown",kdown);
+    window.removeEventListener("keyup",kup);
+    elementToListenTo.removeEventListener("mousedown",mdown);
+    elementToListenTo.removeEventListener("mouseup",mup);
+    elementToListenTo.removeEventListener("mousemove",mmove);
+    elementToListenTo.removeEventListener("contextmenu",cmenu);
+    elementToListenTo.removeEventListener("wheel",scrl);
+}
+function resetInput() {
+    for(var i=0;i<keyPress.length;i++){if(keyPress[i]){keyPress[i]=0}}
+    for(var i=0;i<mousePress.length;i++){if(mousePress[i]){mousePress[i]=0}}
+    scroll=0;
+}
+function kdown(e) {
+    var h=e.keyCode;
+    keyPress[h]=keyPress[h]==[][[]]?1:0;
+    keyDown[h]=1;
+    if(preventedEvents[0]) {e.preventDefault()}
+}
+function kup(e) {
+    var h=e.keyCode;
+    delete keyPress[h];
+    delete keyDown[h];
+}
+function mdown(e) {
+    var h=e.button;
+    mousePress[h]=mousePress[h]==[][[]]?1:0;
+    mouseDown[h]=1;
+    if(preventedEvents[1]) {e.preventDefault()}
+}
+function mup(e) {
+    var h=e.button;
+    delete mousePress[h];
+    delete mouseDown[h];
+}
+function mmove(e) {
+    mousePos.x=e.offsetX/(!canvasScale?autoScale:canvasScale);
+    mousePos.y=e.offsetY/(!canvasScale?autoScale:canvasScale);    
+}
+function cmenu(e) {
+    if(preventedEvents[1]) {e.preventDefault()}
+}
+function scrl(e) {
+    scroll+=-1*(e.deltaY/100);
+    if(preventedEvents[2]) {e.preventDefault()}
+}
+function dist(point1,point2) {
+    let one = (point2.x - point1.x);
+    let two = (point2.y - point1.y);
+    return Math.sqrt((one*one)+(two*two));
+}
+
+function circlecircle(circle1,circle2) {
+    if( dist(circle1,circle2) < (circle1.r + circle2.r)) {
+		return true;
+	} else {
+        return false;
+    }
+}
+
+function circlepoint(circle,point) {
+    if( dist(circle,point) < circle.r) {
+		return true;
+	} else {
+        return false;
+    }
+}
+
+function rectrect(rect1,rect2) {
+    if(rect1.x + rect1.w/2 >= rect2.x - rect2.w/2 &&
+       rect1.x - rect1.w/2 <= rect2.x + rect2.w/2 &&
+       rect1.y + rect1.h/2 >= rect2.y - rect2.h/2 &&
+       rect1.y - rect1.h/2 <= rect2.y + rect2.h/2) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+function rectpoint(rect,point) {
+    if(rect.x + rect.w/2 >= point.x &&
+       rect.x - rect.w/2 <= point.x &&
+       rect.y + rect.h/2 >= point.y &&
+       rect.y - rect.h/2 <= point.y ) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+function circlerect(circle,rect) { //credit: https://yal.cc/rectangle-circle-intersection-test/
+    let rectHalfWidth  = rect.w/2;
+    let rectHalfHeight = rect.h/2;
+    let deltaX = circle.x - Math.max(rect.x - rectHalfWidth, Math.min(circle.x, rect.x + rectHalfWidth));
+    let deltaY = circle.y - Math.max(rect.y - rectHalfHeight, Math.min(circle.y, rect.y + rectHalfHeight));
+    return (deltaX * deltaX + deltaY * deltaY) < (circle.r * circle.r);
+}
+
+function circleOnSideRect(circle,rect) {
+    let rectHalfWidth  = rect.w/2;
+    let rectHalfHeight = rect.h/2;
+    let left   = rect.x - rectHalfWidth;
+    let right  = rect.x + rectHalfWidth;
+    let top    = rect.y - rectHalfHeight;
+    let bottom = rect.y + rectHalfHeight;
+    let cx = circle.x;
+    let cy = circle.y;
+    if(cy < top && cx > left && cx < right) { // top side
+        return 0;
+    } else if(cy > bottom && cx > left && cx < right) { // bottom side
+        return 2;
+    } else if (cx < left && cy > top && cy < bottom) { // left side
+        return 3;
+    } else if (cx > right && cy > top && cy < bottom) { // right side
+        return 1;
+    } else {
+        let returnValue=0; // 0 = top, 1 = right, 2 = bottom, 3 = left
+        let topleft = dist (circle,{x:left,y:top});
+        let topright = dist (circle,{x:right,y:top});
+        let bottomleft = dist (circle,{x:left,y:bottom});
+        let bottomright = dist (circle,{x:right,y:bottom});
+        switch(Math.min(topleft,topright,bottomleft,bottomright)) { // find what corner the cricle is closer to, then determine what side it is closer to
+            case topleft:
+                var m = slope(rect,{x:left,y:top});
+                var mperp = -(1/m);
+                var b = yIntercept(rect,m);
+                var bperp = yIntercept(circle,mperp);
+                var mid = POI(m,b,mperp,bperp);
+                if(cx<mid) {returnValue = 3;} else {returnValue = 0;}
+                break;
+            case topright:
+                var m = slope(rect,{x:right,y:top});
+                var mperp = -(1/m);
+                var b = yIntercept(rect,m);
+                var bperp = yIntercept(circle,mperp);
+                var mid = POI(m,b,mperp,bperp);
+                if(cx<mid) {returnValue = 0;} else {returnValue = 1;}
+                break;
+            case bottomleft:
+                var m = slope(rect,{x:left,y:bottom});
+                var mperp = -(1/m);
+                var b = yIntercept(rect,m);
+                var bperp = yIntercept(circle,mperp);
+                var mid = POI(m,b,mperp,bperp);
+                if(cx<mid) {returnValue = 3;} else {returnValue = 2;}
+                break;
+            case bottomright:
+                var m = slope(rect,{x:right,y:bottom});
+                var mperp = -(1/m);
+                var b = yIntercept(rect,m);
+                var bperp = yIntercept(circle,mperp);
+                var mid = POI(m,b,mperp,bperp);
+                if(cx<mid) {returnValue = 2;} else {returnValue = 1;}
+                break;
+        }
+        return returnValue;
+    }
+}
+
+function rectOnSideRect(rect1,rect2) {
+    let rectHalfWidth2  = rect2.w/2;
+    let rectHalfHeight2 = rect2.h/2;
+    let left2   = rect2.x - rectHalfWidth2;
+    let right2 = rect2.x + rectHalfWidth2;
+    let top2   = rect2.y - rectHalfHeight2;
+    let bottom2 = rect2.y + rectHalfHeight2;
+
+    let rectHalfWidth1  = rect1.w/2;
+    let rectHalfHeight1 = rect1.h/2;
+    let rx1 = rect1.x;
+    let ry1 = rect1.y;
+    let left1   = rx1 - rectHalfWidth1;
+    let right1 = rx1 + rectHalfWidth1;
+    let top1   = ry1 - rectHalfHeight1;
+    let bottom1 = ry1 + rectHalfHeight1;
+    // find what point is closer to the rectangle 
+    let topleft1 = dist (rect2,{x:left1,y:top1});
+    let topright1 = dist (rect2,{x:right1,y:top1});
+    let bottomleft1 = dist (rect2,{x:left1,y:bottom1});
+    let bottomright1 = dist (rect2,{x:right1,y:bottom1});
+    let topmiddle1 = dist (rect2,{x:rx1,y:top1});
+    let rightmiddle1 = dist (rect2,{x:right1,y:ry1});
+    let bottommiddle1 = dist (rect2,{x:rx1,y:bottom1});
+    let leftmiddle1 = dist (rect2,{x:left1,y:ry1});
+    let cx = rx1;
+    let cy = ry1;
+    switch(Math.min(topleft1,topright1,bottomleft1,bottomright1,topmiddle1,rightmiddle1,bottommiddle1,leftmiddle1)) {
+        //set the point we are testing to the closest point to the rectangle
+        case topleft1:
+            cx -= rect1.w/2;
+            cy -= rect1.h/2;
+            break;
+        case topright1:
+            cx += rect1.w/2;
+            cy -= rect1.h/2;
+            break;
+        case bottomleft1:
+            cx -= rect1.w/2;
+            cy += rect1.h/2;
+            break;
+        case bottomright1:
+            cx += rect1.w/2;
+            cy += rect1.h/2;
+            break;
+        case topmiddle1:
+            cy -= rect1.h/2;
+            break;
+        case rightmiddle1:
+            cx += rect1.w/2;
+            break;
+        case bottommiddle1:
+            cy += rect1.h/2;
+            break;
+        case leftmiddle1:
+            cx -= rect1.w/2;
+            break;
+    }
+    if(cy < top2 && cx > left2 && cx < right2) { // top side
+        return 0;
+    } else if(cy > bottom2 && cx > left2 && cx < right2) { // bottom side
+        return 2;
+    } else if (cx < left2 && cy > top2 && cy < bottom2) { // left side
+        return 3;
+    } else if (cx > right2 && cy > top2 && cy < bottom2) { // right side
+        return 1;
+    } else {
+        let returnValue=0; // 0 = top, 1 = right, 2 = bottom, 3 = left
+        let determiningPoint = {x:cx,y:cy};
+        let topleft = dist (determiningPoint,{x:left2,y:top2});
+        let topright = dist (determiningPoint,{x:right2,y:top2});
+        let bottomleft = dist (determiningPoint,{x:left2,y:bottom2});
+        let bottomright = dist (determiningPoint,{x:right2,y:bottom2});
+        switch(Math.min(topleft,topright,bottomleft,bottomright)) { // find what corner the point is closer to, then determine what side it is closer to
+            case topleft:
+                var m = slope(rect2,{x:left2,y:top2});
+                var mperp = -(1/m);
+                var b = yIntercept(rect2,m);
+                var bperp = yIntercept(determiningPoint,mperp);
+                var mid = POI(m,b,mperp,bperp);
+                if(cx<mid) {returnValue = 3;} else {returnValue = 0;}
+                break;
+            case topright:
+                var m = slope(rect2,{x:right2,y:top2});
+                var mperp = -(1/m);
+                var b = yIntercept(rect2,m);
+                var bperp = yIntercept(determiningPoint,mperp);
+                var mid = POI(m,b,mperp,bperp);
+                if(cx<mid) {returnValue = 0;} else {returnValue = 1;}
+                break;
+            case bottomleft:
+                var m = slope(rect2,{x:left2,y:bottom2});
+                var mperp = -(1/m);
+                var b = yIntercept(rect2,m);
+                var bperp = yIntercept(determiningPoint,mperp);
+                var mid = POI(m,b,mperp,bperp);
+                if(cx<mid) {returnValue = 3;} else {returnValue = 2;}
+                break;
+            case bottomright:
+                var m = slope(rect2,{x:right2,y:bottom2});
+                var mperp = -(1/m);
+                var b = yIntercept(rect2,m);
+                var bperp = yIntercept(determiningPoint,mperp);
+                var mid = POI(m,b,mperp,bperp);
+                if(cx<mid) {returnValue = 2;} else {returnValue = 1;}
+                break;
+        }
+        return returnValue;
+    }
+}
+
+function slope(point1,point2) {
+    return ((point2.y-point1.y)/(point2.x-point1.x));
+}
+
+function yIntercept(point,slope) {
+    return point.y - (slope * point.x);
+}
+
+function POI(m1,b1,m2,b2) {
+    x = (b2 - b1) / (m1 - m2);
+    return x;
+    //y = m1 * x + b1;
+}
+
+function ifRectOnEdgeBounce(rect) {
+    let rx = rect.x;
+    let ry = rect.y;
+    let rw = rect.w/2;
+    let rh = rect.h/2;
+    if(rx+rw>edge.right) {
+        rect.v.x *= -1;
+        rect.x = edge.right-rw;
+    }
+    if(rx-rw<edge.left) {
+        rect.v.x *= -1;
+        rect.x = edge.left+rw;
+    }
+    if(ry+rh>edge.bottom) {
+        rect.v.y *= -1;
+        rect.y = edge.bottom-rh;
+    }
+    if(ry-rh<edge.top) {
+        rect.v.y *= -1;
+        rect.y = edge.top+rh;
+    }
+}
+
+function ifCircleOnEdgeBounce(circle) {
+    let cx = circle.x;
+    let cy = circle.y;
+    let cr = circle.r;
+    if(cx+cr>edge.right) {
+        circle.v.x *= -1;
+        circle.x = edge.right-cr;
+    }
+    if(cx-cr<edge.left) {
+        circle.v.x *= -1;
+        circle.x = edge.left+cr;
+    }
+    if(cy+cr>edge.bottom) {
+        circle.v.y *= -1;
+        circle.y = edge.bottom-cr;
+    }
+    if(cy-cr<edge.top) {
+        circle.v.y *= -1;
+        circle.y = edge.top+cr;
+    }
+}
+// create globals
+var canvases={cvs:null,ctx:null,buffer1cvs:null,buffer1ctx:null,buffer2cvs:null,buffer2ctx:null}, // visable and hidden canvases
+cw, // canvas width
+ch, // canvas height
+camera={zoom:1,angle:0,x:0,y:0}, // affects how everything is drawn
+updateFPS=60,
+gameStarted=false,
+drawMode=0, // 0=normal, 1=zoomed, 2=zoomed/rotated, set automatically depending on camera
+absDraw=false,
+curCtx, // what canvas to draw to
+maxCvsSize, // used by second buffer
+canvasScale=1,
+difx=0, // offsets for drawing
+dify=0,
+seperateInputLoop=true,
+edge={top:null,bottom:null,left:null,right:null}, // used by if___OnEdgeBounce, set to canvas size at setup, can be changed whenever
+drawLimitLeft,
+drawLimitRight,
+drawLimitTop,
+drawLimitBottom,
+sizeDif,
+bug="\uD83D\uDC1B",
+loadingCircle,
+loadAng=0,
+optionsHover=0,
+pauseHover=0,
+optionsMenu=false,
+optionsButtons={},
+clickSound,
+paused=false,
+screenSize="1:1",
+autoScale=1,
+
+images=[], // put image paths here
+imagePaths=[],
+imgs=[],
+sprites={}, // loaded images
+
+audio=[], // put audio paths here
+audioPaths=[],
+sounds={}, // loaded sounds
+abuffer = [], // audio nodes shoved here
+volumeList = [], // gain nodes shoved here
+audioLoadedLength=0,
+volume={sfx:1,bgm:1};
+/* options
+    future:
+        modefileable checklist
+        key bindings
+*/
+
+cursor = {sprite:null,alignment:1,show:true}, // 0=topleft, 1=centered
+mouseOnCanvas=false;
+
+const acceptableChars="qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890_-. ";//for image names
+
+const AudioContext = window.AudioContext||window.webkitAudioContext;
+var context;
+var sfxVolumeNode;
+var bmgVolumeNode;
+
+document.getElementById("game").onmouseout = function()   {mouseOnCanvas = false;}
+document.getElementById("game").onmouseover = function()   {mouseOnCanvas = true;}
+
+//setup canvases and input
+function setup(physicsFPS) {
+    updateFPS = physicsFPS;
+    
+    canvases.cvs = document.getElementById("game");
+    canvases.ctx = canvases.cvs.getContext("2d", { alpha: false });
+
+    canvases.cvs.onmousedown = function () {if(!gameStarted){loadImagesAndSounds();gameStarted=true;}}
+
+    createCanvas("buffer1");
+    createCanvas("buffer2");
+
+    canvases.ctx.imageSmoothingEnabled = false;
+    canvases.buffer1ctx.imageSmoothingEnabled = false;
+    canvases.buffer2ctx.imageSmoothingEnabled = false;
+
+    maxCvsSize=Math.max(canvases.cvs.width,canvases.cvs.height);
+    sizeDif=maxCvsSize-Math.min(canvases.cvs.width,canvases.cvs.height);
+    cw=canvases.cvs.width;
+    ch=canvases.cvs.height;
+    
+    edge={top:0,bottom:ch,left:0,right:cw};
+
+    addFont();
+    addStyle();
+
+    addListenersTo(canvases.cvs);
+
+    curCtx = canvases.ctx;
+    requestAnimationFrame(startButton);
+    function startButton() {
+        curCtx.fillStyle="#2d2d2d";
+        curCtx.fillRect(0,0,cw,ch);//debugger;
+        circle(cw/2,ch/2,27,"#066312");
+        circle(cw/2,ch/2,23,"#149124");
+        shape(cw/2,ch/2,[{x:-7,y:-15},{x:-7,y:15},{x:15,y:0}],"#47f55d");
+        if(!gameStarted) {requestAnimationFrame(startButton);}
+    }
+}
+
+function drawLoop() {
+    cw=canvases.cvs.width;
+    ch=canvases.cvs.height;
+    scaleCanvases();
+
+    switchDrawMode();
+    
+    resizeBuffers();
+
+    clearCanvases();
+
+    var limitModifyer = 0;
+    if(drawMode==2) {limitModifyer=canvases.buffer2cvs.width-maxCvsSize;}
+    drawLimitLeft   = -camera.x - (drawMode==2?sizeDif:0) - limitModifyer;
+    drawLimitRight  = -camera.x + maxCvsSize + (drawMode==2?sizeDif:0) + limitModifyer;
+    drawLimitTop    = -camera.y -(drawMode==2?sizeDif:0) - limitModifyer;
+    drawLimitBottom = -camera.y + maxCvsSize + (drawMode==2?sizeDif:0) + limitModifyer;
+
+    draw();
+    
+    render();
+
+    curCtx=canvases.ctx;
+    difx=0;dify=0;
+    var camCache = {x:camera.x,y:camera.y};
+    var drawModeCache = drawMode;
+    camera.x=0;camera.y=0;
+    drawMode=0;
+    absDraw=true;
+    absoluteDraw();
+    absDraw=false;
+
+    drawButtons();
+    drawOptionsMenu();
+    drawCursor();
+
+    drawMode=drawModeCache;
+
+    camera.x = camCache.x;
+    camera.y = camCache.y;
+
+    requestAnimationFrame(drawLoop);
+}
+
+function updateLoop() {
+    if(seperateInputLoop==false) {
+        handleOptionsInput();
+    }
+    sfxVolumeNode.gain.value = volume.sfx;
+    bmgVolumeNode.gain.value = volume.bgm;
+    if(!paused) {
+        update();
+    }
+
+    if(seperateInputLoop==false) {
+        resetInput();
+    }
+}
+
+
+function inputLoop() {
+    handleOptionsInput();
+    if(!paused) {
+        input();
+    }
+
+    resetInput();
 }
\ No newline at end of file
diff --git a/scripts/index.js b/docs/scripts/index.js
similarity index 86%
rename from scripts/index.js
rename to docs/scripts/index.js
index a9e60f6..6c8fd79 100644
--- a/scripts/index.js
+++ b/docs/scripts/index.js
@@ -1,29 +1,29 @@
-images = [
-    ""
-];
-
-audio = [
-    ""
-];
-
-function update() {
-
-}
-
-function input() {
-
-}
-
-function draw() {
-
-}
-
-function absoluteDraw() {
-
-}
-
-function onAssetsLoaded() {
-
-}
-
+images = [
+    ""
+];
+
+audio = [
+    ""
+];
+
+function update() {
+
+}
+
+function input() {
+
+}
+
+function draw() {
+
+}
+
+function absoluteDraw() {
+
+}
+
+function onAssetsLoaded() {
+
+}
+
 setup(60);
\ No newline at end of file