1 line
15 KiB
HTML
1 line
15 KiB
HTML
<head>
|
|
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
<meta name="apple-mobile-web-app-title" content="mkjs">
|
|
<meta name="format-detection" content="telephone=no">
|
|
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, user-scalable=no, viewport-fit=cover">
|
|
|
|
<!-- Client Code Includes -->
|
|
|
|
<script src="code/engine/largeSphereCollider.js"></script>
|
|
<script src="code/engine/collisionTypes.js"></script>
|
|
<script src="code/engine/mkdsConst.js"></script>
|
|
<script src="code/engine/ingameRes.js"></script>
|
|
<script src="code/engine/itemController.js"></script>
|
|
<script src="code/IndexedDBShim.min.js"></script>
|
|
|
|
<script src="code/engine/storage/fileStore.js"></script>
|
|
|
|
<script src="code/engine/controls/controlDefault.js"></script>
|
|
<script src="code/engine/controls/controlRaceCPU.js"></script>
|
|
<script src="code/engine/controls/controlNetwork.js"></script>
|
|
|
|
<script src="code/engine/cameras/cameraIngame.js"></script>
|
|
<script src="code/engine/cameras/cameraSpectator.js"></script>
|
|
<script src="code/engine/cameras/cameraIntro.js"></script>
|
|
|
|
<script src="code/engine/scenes/sceneDrawer.js"></script>
|
|
<script src="code/engine/scenes/courseScene.js"></script>
|
|
<script src="code/engine/scenes/clientScene.js"></script>
|
|
<script src="code/engine/scenes/singleScene.js"></script>
|
|
|
|
<script src="code/engine/2d/tileFlattener.js"></script>
|
|
|
|
<script src="code/ui/race3DUI.js"></script>
|
|
|
|
<script src="code/formats/net/netKart.js"></script>
|
|
|
|
<script src="code/entities/objDatabase.js"></script>
|
|
<script src="code/entities/trafficCar.js"></script>
|
|
<script src="code/entities/water.js"></script>
|
|
<script src="code/entities/itembox.js"></script>
|
|
<script src="code/entities/decorations.js"></script>
|
|
<script src="code/entities/rotatingGear.js"></script>
|
|
<script src="code/entities/bowserPlatforms.js"></script>
|
|
<script src="code/entities/soundMaker.js"></script>
|
|
|
|
<script src="code/particles/itemboxShard.js"></script>
|
|
<script src="code/particles/nitroParticle.js"></script>
|
|
<script src="code/particles/nitroEmitter.js"></script>
|
|
|
|
<script src="code/entities/shell.js"></script>
|
|
<script src="code/entities/kart.js"></script>
|
|
<script src="code/entities/kartItems.js"></script>
|
|
|
|
<script src="code/entities/items/bananas.js"></script>
|
|
<script src="code/entities/items/powerups.js"></script>
|
|
<script src="code/entities/items/shells.js"></script>
|
|
<script src="code/entities/item.js"></script>
|
|
|
|
<script src="code/formats/kcl.js"></script>
|
|
|
|
<script src="code/formats/ndsFS.js"></script>
|
|
|
|
<script src="code/formats/nitro.js"></script>
|
|
<script src="code/formats/nsbtx.js"></script>
|
|
<script src="code/formats/nsbmd.js"></script>
|
|
<script src="code/formats/nsbta.js"></script>
|
|
<script src="code/formats/nsbca.js"></script>
|
|
<script src="code/formats/nsbtp.js"></script>
|
|
<script src="code/formats/nftr.js"></script>
|
|
<script src="code/formats/narc.js"></script>
|
|
<script src="code/formats/lz77.js"></script>
|
|
<script src="code/formats/spa.js"></script>
|
|
|
|
<script src="code/formats/2d/ncer.js"></script>
|
|
<script src="code/formats/2d/ncgr.js"></script>
|
|
<script src="code/formats/2d/nclr.js"></script>
|
|
<script src="code/formats/2d/nscr.js"></script>
|
|
|
|
<script src="code/formats/nkm.js"></script>
|
|
<script src="code/formats/kartphysicalparam.js"></script>
|
|
<script src="code/formats/kartoffsetdata.js"></script>
|
|
|
|
<script src="code/render/nitroRender.js"></script>
|
|
<script src="code/render/nitroShaders.js"></script>
|
|
<script src="code/render/shadowRender.js"></script>
|
|
<script src="code/render/nitroAnimator.js"></script>
|
|
|
|
<script src="code/glmatrix/gl-matrix.js"></script>
|
|
|
|
<script src="code/formats/sdat.js"></script>
|
|
<script src="code/formats/swav.js"></script>
|
|
<script src="code/formats/swar.js"></script>
|
|
<script src="code/formats/sbnk.js"></script>
|
|
<script src="code/formats/sseq.js"></script>
|
|
<script src="code/formats/ssar.js"></script>
|
|
<script src="code/audio/sseqPlayer.js"></script>
|
|
<script src="code/audio/nitroAudio.js"></script>
|
|
|
|
<!-- Inline code (because that's always a good idea) -->
|
|
|
|
<script>
|
|
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
|
|
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
|
|
window.requestAnimationFrame = requestAnimationFrame;
|
|
|
|
var files = {};
|
|
var fileQuota;
|
|
var filesLoaded = 0;
|
|
var mobile = (function(a,b){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))return true})(navigator.userAgent||navigator.vendor||window.opera);
|
|
var mainRT;
|
|
var waitForROM = false;
|
|
|
|
window.onload = function(argument) {
|
|
window.simpleMatStack = {dat:mat4.create(), built:true};
|
|
init();
|
|
}
|
|
|
|
window.onerror = function(msg, url, line, col, e) {
|
|
var stack = e.stack.replace(/^[^\(]+?[\n$]/gm, '')
|
|
.replace(/^\s+at\s+/gm, '')
|
|
.replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@')
|
|
.split('\n');
|
|
console.log(stack);
|
|
}
|
|
|
|
window.onerror = function(error, h, j) {
|
|
alert("ERROR: "+error+", "+h+", "+j);
|
|
}
|
|
|
|
function loadFile(url) {
|
|
var xml = new XMLHttpRequest();
|
|
xml.open("GET", url, true);
|
|
xml.responseType = "arraybuffer";
|
|
xml.onload = function() {
|
|
files[url] = xml.response;
|
|
if (++filesLoaded == fileQuota) init();
|
|
}
|
|
xml.send();
|
|
}
|
|
|
|
function init() {
|
|
var canvas = document.getElementById("canvas3d");
|
|
canvas.addEventListener("click", lockPtr);
|
|
fileStore.requestGameFiles(initNitro);
|
|
}
|
|
|
|
function initNitro(rom) {
|
|
gl = initGL(document.getElementById("canvas3d"));
|
|
gameROM = new ndsFS(rom);
|
|
|
|
nitroRender.init(gl);
|
|
shadowRender.init(gl);
|
|
sceneDrawer.init(gl);
|
|
objDatabase.init();
|
|
|
|
nitroAudio.init(new sdat(gameROM.getFile("/data/Sound/sound_data.sdat")));
|
|
|
|
var ctx = nitroAudio.ctx;
|
|
buf = ctx.createBuffer(1, 1, 44000);
|
|
osc = ctx.createBufferSource();
|
|
osc.buffer = buf;
|
|
osc.connect(ctx.destination);
|
|
if (osc.noteOn) osc.start = osc.noteOn;
|
|
|
|
var res = new IngameRes(gameROM);
|
|
vert = 0;
|
|
|
|
var canvas = document.getElementById("canvas3d");
|
|
|
|
document.addEventListener("mousemove", mouseMove);
|
|
document.addEventListener("keydown", keyDown);
|
|
document.addEventListener("keyup", keyUp);
|
|
|
|
document.addEventListener("touchstart", touchStart, { passive: false });
|
|
document.addEventListener("touchend", touchEnd, { passive: false });
|
|
document.addEventListener("touchcancel", touchCancel, { passive: false });
|
|
document.addEventListener("touchmove", touchMove, { passive: false });
|
|
|
|
canvas.addEventListener('click', function() {
|
|
if (!osc.donezo) {
|
|
osc.start(0);
|
|
osc.donezo = true;
|
|
}
|
|
});
|
|
//mainScene = new clientScene("ws://192.168.1.13:8081", 0, res)
|
|
mainScene = new singleScene("mkds/"+window.prompt("Select a course to load. (0 to 31, eg rainbow road = 15)"), 0, res)
|
|
|
|
|
|
//load course
|
|
/*var cDir = MKDSCONST.COURSEDIR+MKDSCONST.COURSES[window.prompt("Select a course to load. (0 to 31, eg rainbow road = 15)")]
|
|
|
|
//var cDir = MKDSCONST.COURSEDIR+MKDSCONST.COURSES[1];
|
|
|
|
var mainNarc = new narc(lz77.decompress(files["snow_course.carc"]));
|
|
var texNarc = new narc(lz77.decompress(files["snow_courseTex.carc"]));
|
|
|
|
//var mainNarc = new narc(lz77.decompress(gameROM.getFile(cDir+".carc")));
|
|
//var texNarc = new narc(lz77.decompress(gameROM.getFile(cDir+"Tex.carc")));
|
|
|
|
var chars = [];
|
|
for (var i=0; i<31; i++) {
|
|
chars.push({charN:Math.floor(Math.random()*12), kartN:Math.floor(Math.random()*0x24), controller:controlRaceCPU, raceCam:false});
|
|
}
|
|
chars.push({charN:Math.floor(Math.random()*12), kartN:Math.floor(Math.random()*0x24), controller:((prompt("Type y to gain control of last kart.")=="y")?controlDefault:controlRaceCPU), raceCam:true})
|
|
|
|
mainScene = new courseScene(mainNarc, texNarc,
|
|
chars, {}, res);
|
|
|
|
//var cDir = MKDSCONST.COURSEDIR+MKDSCONST.COURSES[12];
|
|
//var mainNarc = new narc(lz77.decompress(gameROM.getFile(cDir+".carc")));
|
|
//var texNarc = new narc(lz77.decompress(gameROM.getFile(cDir+"Tex.carc")));
|
|
|
|
// mainScene2 = new courseScene(mainNarc, texNarc,
|
|
// chars, {}, res);*/
|
|
|
|
big();
|
|
render();
|
|
}
|
|
|
|
var keysArray = new Array(255);
|
|
var touches = [];
|
|
|
|
var timeSync = 0;
|
|
var lastTime = Date.now();
|
|
function render() {
|
|
timeSync += Date.now()-lastTime;
|
|
lastTime = Date.now();
|
|
|
|
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
|
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
|
|
|
while (timeSync>0) {
|
|
mainScene.update();
|
|
processTouches();
|
|
if (timeSync > 1000) timeSync = 1000; //don't run way too many frames.
|
|
timeSync -= 1000/60;
|
|
}
|
|
|
|
nitroAudio.tick();
|
|
//mainScene2.update();
|
|
|
|
mainScene.render();
|
|
//sceneDrawer.drawWithShadow(gl, mainScene2, gl.viewportWidth/2, 0, gl.viewportWidth/2, gl.viewportHeight)
|
|
|
|
window.requestAnimationFrame(render);
|
|
}
|
|
|
|
function keyDown(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
keysArray[e.keyCode] = true;
|
|
}
|
|
|
|
function keyUp(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
keysArray[e.keyCode] = false;
|
|
}
|
|
|
|
//touch handlers
|
|
//touches [{id: number, x:number (0-1), y:number (0-1), pressed:boolean, released:boolean, lastx:number (0-1), lasty:number (0-1)}]
|
|
|
|
function processTouches() {
|
|
for (var i=0; i<touches.length; i++) {
|
|
var touch = touches[i];
|
|
touch.pressed = false;
|
|
if (touch.released) touches.splice(i--, 1);
|
|
}
|
|
}
|
|
|
|
function setTouchPos(obj, touch) {
|
|
obj.lastx = obj.x;
|
|
obj.lasty = obj.y;
|
|
|
|
obj.x = touch.clientX / document.body.clientWidth;
|
|
obj.y = touch.clientY / document.body.clientHeight;
|
|
}
|
|
|
|
function getTouchObj(touch) {
|
|
console.log('getting obj')
|
|
for (var i=0; i<touches.length; i++) {
|
|
var mkTouch = touches[i];
|
|
if (mkTouch.id == touch.identifier) {
|
|
setTouchPos(mkTouch, touch);
|
|
return mkTouch;
|
|
}
|
|
}
|
|
//couldn't find this touch. give it a new object.
|
|
var result = {id: touch.identifier};
|
|
setTouchPos(result, touch);
|
|
touches.push(result);
|
|
return result;
|
|
}
|
|
|
|
function touchStart(e) {
|
|
//identifier
|
|
if (!osc.donezo) {
|
|
osc.start(0);
|
|
osc.donezo = true;
|
|
}
|
|
e.preventDefault();
|
|
for (var i=0; i<e.changedTouches.length; i++) {
|
|
var obj = getTouchObj(e.changedTouches[i]);
|
|
obj.pressed = true;
|
|
}
|
|
}
|
|
|
|
function touchEnd(e) {
|
|
e.preventDefault();
|
|
for (var i=0; i<e.changedTouches.length; i++) {
|
|
var obj = getTouchObj(e.changedTouches[i]);
|
|
obj.released = true;
|
|
}
|
|
}
|
|
|
|
function touchMove(e) {
|
|
e.preventDefault();
|
|
for (var i=0; i<e.changedTouches.length; i++) {
|
|
var obj = getTouchObj(e.changedTouches[i]);
|
|
}
|
|
}
|
|
|
|
function touchCancel(e) {
|
|
e.preventDefault();
|
|
for (var i=0; i<e.changedTouches.length; i++) {
|
|
var obj = getTouchObj(e.changedTouches[i]);
|
|
obj.released = true;
|
|
}
|
|
}
|
|
|
|
function lockPtr(e) {
|
|
if (waitForROM) {
|
|
document.getElementById("fileIn").click();
|
|
}
|
|
}
|
|
|
|
function mouseMove(e) {
|
|
var movementX = e.movementX ||
|
|
e.mozMovementX ||
|
|
e.webkitMovementX ||
|
|
0;
|
|
|
|
var movementY = e.movementY ||
|
|
e.mozMovementY ||
|
|
e.webkitMovementY ||
|
|
0;
|
|
}
|
|
|
|
function initGL(canvas) {
|
|
try {
|
|
var gl = canvas.getContext('webgl', {premultipliedAlpha: false, stencil: true, antialias: !mobile})// || canvas.getContext("experimental-webgl");
|
|
gl.clearColor(0,0,0,1);
|
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
gl.enable(gl.DEPTH_TEST);
|
|
gl.viewportWidth = canvas.width;
|
|
gl.viewportHeight = canvas.height;
|
|
return gl;
|
|
} catch (err) {
|
|
alert("WebGL could not be initialized.")
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function big() {
|
|
var element = document.getElementById("canvas3d");
|
|
element.height = window.innerHeight;
|
|
element.width = window.innerWidth;
|
|
fixScale();
|
|
}
|
|
|
|
function fixScale() {
|
|
if (gl == null) return;
|
|
var element = document.getElementById("canvas3d");
|
|
gl.viewportWidth = element.width;
|
|
gl.viewportHeight = element.height;
|
|
}
|
|
|
|
window.addEventListener("resize", big);
|
|
</script>
|
|
|
|
</head>
|
|
|
|
<body style="margin:0; background-color:black; color: white;">
|
|
|
|
<canvas height="720" width="1280" id="canvas3d"></canvas>
|
|
<!--
|
|
<canvas height="720" width="1280" id="canvas"></canvas>
|
|
<br>
|
|
<select id="kcls">
|
|
<option value="airship_course.kcl">airship_course.kcl</option>
|
|
<option value="bowsers_castle.kcl">bowsers_castle.kcl</option>
|
|
<option value="cheep_cheep_beach.kcl">cheep_cheep_beach.kcl</option>
|
|
<option value="delfino.kcl">delfino.kcl</option>
|
|
<option value="desert.kcl">desert.kcl</option>
|
|
<option value="figure_8.kcl">figure_8.kcl</option>
|
|
<option value="luigi_circuit_gcn.kcl">luigi_circuit_gcn.kcl</option>
|
|
<option value="luigis_mansion.kcl">luigis_mansion.kcl</option>
|
|
<option value="peach_gardens.kcl">peach_gardens.kcl</option>
|
|
<option value="tick_tock_clock.kcl">tick_tock_clock.kcl</option>
|
|
<option value="wario_stadium.kcl">wario_stadium.kcl</option>
|
|
<option value="yoshi_falls.kcl">yoshi_falls.kcl</option>
|
|
<option value="block.kcl">block.kcl</option>
|
|
<option value="mkwii.kcl">mkwii.kcl</option>
|
|
</select>
|
|
|
|
-->
|
|
|
|
<input type="file" id="fileIn" style="display:none;">
|
|
|
|
</body> |