Massive Update

This commit is contained in:
TheEmeraldStarr 2020-11-11 19:05:10 -08:00
parent d2547cf7b2
commit 003b5da951
61 changed files with 1660 additions and 126179 deletions

View file

@ -117,8 +117,8 @@ This is an example of DNS records involving Heroku. Self-hosting will require `A
<img src="https://cdn.discordapp.com/attachments/725506757291671663/756659513179766844/unknown.png" width="500" height="154"></img> <img src="https://cdn.discordapp.com/attachments/725506757291671663/756659513179766844/unknown.png" width="500" height="154"></img>
- `a.deepsoil.ml` is being used for Node Unblocker. - `a.deepsoil.ml` is being used for Node Unblocker.
- `c.deepsoil.ml` is being used for Powermouse. - `p.deepsoil.ml` is being used for Powermouse.
- `cdn.deepsoil.ml` is being used for Via. - `pd.deepsoil.ml` is being used for PyDodge B.
- `cdn.deepsoil.ml` is being used for a private Alloy host on the official sites. - `cdn.deepsoil.ml` is being used for a private Alloy host on the official sites.
As stated previously, Holy Unblocker is hosted locally with Alloy. As stated previously, Holy Unblocker is hosted locally with Alloy.

5
app.js
View file

@ -1,3 +1,8 @@
/* -----------------------------------------------
/* Author : QuiteAFancyEmerald and YÖCTDÖNALD'S with help from MikeLime and SexyDuceDuce
/* MIT license: http://opensource.org/licenses/MIT
/* ----------------------------------------------- */
const const
express = require('express'), express = require('express'),
app = express(), app = express(),

View file

@ -1,3 +1,8 @@
/* -----------------------------------------------
/* Author : Divide
/* MIT license: http://opensource.org/licenses/MIT
/* ----------------------------------------------- */
var fs = require('fs'), var fs = require('fs'),
path = require('path'), path = require('path'),
mime = require('mime-types'), mime = require('mime-types'),

13
package-lock.json generated
View file

@ -13,6 +13,14 @@
"negotiator": "0.6.2" "negotiator": "0.6.2"
} }
}, },
"alloyproxy": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/alloyproxy/-/alloyproxy-1.0.0.tgz",
"integrity": "sha512-2MnpZduvj7YwOIsR3r07r4YXO12FpyN7xcZpWVTHtYC5xofXLgqsn9QZLpl4FgaePKqJkT9lT6CMIUFKF0IR4A==",
"requires": {
"ws": "^7.4.0"
}
},
"array-flatten": { "array-flatten": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@ -434,6 +442,11 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
}, },
"ws": {
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz",
"integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ=="
},
"xss": { "xss": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/xss/-/xss-1.0.8.tgz", "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.8.tgz",

View file

@ -15,6 +15,7 @@
"author": "Titanium Network", "author": "Titanium Network",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"alloyproxy": "^1.0.0",
"cookie-parser": "^1.4.5", "cookie-parser": "^1.4.5",
"express": "^4.17.1", "express": "^4.17.1",
"express-session": "^1.17.1", "express-session": "^1.17.1",

File diff suppressed because one or more lines are too long

View file

@ -1,10 +0,0 @@
// configuration
var opts = {
romReaders: [
new GameboyJS.RomFileReader(),
new GameboyJS.RomDropFileReader(document.getElementById('dropzone'))
]
};
var g = new GameboyJS.Gameboy(document.getElementById('canvas'), opts);
g.setSoundEnabled(document.getElementById('sound-enable').checked);
g.setScreenZoom(document.getElementById('screen-zoom').value);

View file

@ -1,3 +1,8 @@
/* -----------------------------------------------
/* Authors: OlyB
/* MIT license: http://opensource.org/licenses/MIT
/* GFiles - Edited
/* ----------------------------------------------- */
function gsearch() { function gsearch() {
var e, t, n, a; var e, t, n, a;
for (e = document.getElementById("gsearchbar").value.toUpperCase(), t = document.getElementById("glist"), a = 0; a < t.querySelectorAll("a[href]").length; a++)(n = t.getElementsByTagName("a")[a]).innerHTML.toUpperCase().indexOf(e) > -1 ? n.style.display = "block" : n.style.display = "none" for (e = document.getElementById("gsearchbar").value.toUpperCase(), t = document.getElementById("glist"), a = 0; a < t.querySelectorAll("a[href]").length; a++)(n = t.getElementsByTagName("a")[a]).innerHTML.toUpperCase().indexOf(e) > -1 ? n.style.display = "block" : n.style.display = "none"

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,10 @@
/* -----------------------------------------------
/* Authors: YÖCTDÖNALD'S and OlyB
/* MIT license: http://opensource.org/licenses/MIT
/* Tab Cloak - Script
/* v1.5.0
/* ----------------------------------------------- */
/*Title & Icon Presets*/ /*Title & Icon Presets*/
let titles = icons = []; let titles = icons = [];

View file

@ -1,3 +1,8 @@
/* -----------------------------------------------
/* Author: Divide
/* MIT license: http://opensource.org/licenses/MIT
/* Cloak
/* ----------------------------------------------- */
document.onkeydown = (function(e) { document.onkeydown = (function(e) {
e.preventDefault(); e.preventDefault();
if (e.which == 17) cip = true; if (e.which == 17) cip = true;

View file

@ -1,220 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<!-- Important: Use &#8203; to mess with keywords. -->
<title>H&#8203;oly Unb&#8203;loc&#8203;ke&#8203;r</title>
<meta name="description" content="G&#8203;et p&#8203;ast in&#8203;te&#8203;r&#8203;net ce&#8203;n&#8203;s&#8203;or&#8203;sh&#8203;ip tod&#8203;a&#8203;y!
:D">
<link rel="icon" type="image/png" sizes="32x32" href="assets/img/i.png">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Montserrat+Alternates">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web:400,600,700">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/fonts/ionicons.min.css">
<link rel="stylesheet" href="assets/css/styles.css">
<!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>
<script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script>
<script async src="https://arc.io/widget.js#2BzvQ1em"></script>
<!--<script src="assets/js/im-runtime.js"></script>-->
</head>
<body>
<div id="particles-js">
<script>
/* particlesJS.load(@dom-id, @path-json, @callback (optional)); */
particlesJS.load('particles-js', 'particles.json', function() {
console.log('particlesjs loaded.......');
});
</script>
<div>
<h1 id="holy-unblocker">Documentation</h1>
<p>A website that can be used to bypass web filters; both extension and firewall. This is the official documentation for Holy Unblocker, a rather fancy website with some cool dynamic backgrounds while also focusing with detail put into the design and mechanics overall. Also has cool features like custom Tab Cloaks and with more to come. Works on a large number of sites including YouTube (Full Quality Support), Discord, CoolMathGames and more! Be sure to check the various branches as I update Holy Unblocker often with open access to yet to be released versions.</p>
<p>Official Site: <a href="https://www.holyubofficial.net">https://www.holyubofficial.net</a></p>
<p>Be sure to join Titanium Network&#39;s Discord for more official site links: <a href="https://discord.com/invite/tgT48PH">https://discord.com/invite/tgT48PH</a></p>
<p><a href="https://heroku.com/deploy?template=https://github.com/QuiteAFancyEmerald/HolyUnblockerPublic" title="Deploy to Heroku"><img alt="Deploy to Heroku" src="https://raw.githubusercontent.com/QuiteAFancyEmerald/HolyUnblockerPublic/master/public/assets/img/heroku.svg?raw" width="140" height="30"><img></a>
&nbsp;
<a href="https://azuredeploy.net/" title="Deploy to Azure"><img alt="Deploy to Azure" src="https://raw.githubusercontent.com/QuiteAFancyEmerald/HolyUnblockerPublic/master/public/assets/img/azure.svg?raw" width="140" height="30"><img></a>
&nbsp;
<a href="https://repl.it/github/QuiteAFancyEmerald/HolyUnblockerPublic" title="Run on Repl.it"><img alt="Run on Repl.it" src="https://raw.githubusercontent.com/QuiteAFancyEmerald/HolyUnblockerPublic/master/public/assets/img/replit.svg?raw" width="140" height="30"><img></a>
&nbsp;
<a href="https://glitch.com/edit/#!/import/github/QuiteAFancyEmerald/HolyUnblockerPublic" title="Remix on Glitch"><img alt="Remix on glitch" src="https://raw.githubusercontent.com/QuiteAFancyEmerald/HolyUnblockerPublic/master/public/assets/img/glitch.svg?raw" width="140" height="30"><img></a></p>
<h2 id="table-of-contents-">Table of contents:</h2>
<ul>
<li><a href="#how-to-install">Setup</a>
<ul>
<li><a href="#structure">Structure</a>
<ul>
<li><a href="#structure-information">Structure Information</a></li>
<li><a href="#details-of-public">Static Files</a></li>
<li><a href="#scripts-located-in-expr">Proxy Scripts</a></li>
<li><a href="#details-of-authjs">Cookie Auth</a></li>
</ul>
</li>
<li><a href="#future-additions">Future Additions</a></li>
<li><a href="#vauge-explanation-for-beginners-with-external-and-hosting">Beginner&#39;s Explanation</a>
<ul>
<li><a href="#list-of-some-good-hosting-options">Hosting Providers</a></li>
<li><a href="#heroku-steps">Heroku Setup</a></li>
<li><a href="#freenomdomain-steps">Domain Setup</a></li>
<li><a href="#cloudflare-steps">Cloudflare Setup</a></li>
<li><a href="#workspace-configurations">Workspace Configurations</a></li>
</ul>
</li>
<li><a href="#more-information">More Information</a></li>
</ul>
</li>
</ul>
<h2 id="how-to-setup">How to Setup</h2>
<p>Either use the button above to deploy to Heroku or do the below:</p>
<pre><code>git <span class="hljs-keyword">clone</span> <span class="hljs-title">https</span>://github.com/QuiteAFancyEmerald/HolyUnblockerPublic.git
cd HolyUnblockerPublic
npm install
npm <span class="hljs-literal">start</span>
</code></pre>
<p>The default place for the proxy when its started is <code>http://localhost:8081</code> but you can change it if needed in config.json</p>
<p>This website has been hosted locally on Alloy Proxy. More more information go to the Alloy Proxy repo below.</p>
<h2 id="structure">Structure</h2>
<ul>
<li><code>index.html</code> : The official homepage of the site.</li>
<li><code>surf.html</code> : Surf Freely page, page offers to be redirected to either Alloy or Node.</li>
<li><code>alloy.html</code> : Alloy Proxy page, configured as recommended with Alloy Proxy.</li>
<li><code>node.html</code> : Links to a subdomain for Node Unblocker. I left it in just in case you would like to setup the site differently.</li>
<li><code>pmprox.html</code> : Links to a subdomain for Powermouse. I left it in just in case you would like to setup the site differently.</li>
<li><code>gtools.html</code> : Games page, help from @BinBashBanana and @kinglalu.</li>
<li><code>info.html</code> : WIP Documentation.</li>
<li><code>discordhub.html</code> : Hub for the discord proxy and its links.</li>
<li><code>discordprox.html</code> : Links to a discord proxied through Alloy.</li>
<li><code>pydodge.html</code> : Links to a subdomain with PyDodge B. Created by OlyB from a modified Via Proxy.</li>
<li><code>flash.html</code> : Games page for flash games, credits given to @BinBashBanana and Titanium Network for its assets.</li>
<li><code>icons.html</code> : Information regarding Settings Menu page. Added this in for standard users.</li>
<li><code>terms.html</code> : Terms of Services, AUP and Privacy Policy page.</li>
<li><code>gba.html</code> : Locally hosted Gameboy Emulator.</li>
<li><code>krunker.html</code> : An iframe version of Krunker with keyword changes. Can be removed if not needed.</li>
<li><code>youtube.html</code> : An proxied version of Youtube running off of the locally hosted Alloy Proxy.</li>
<li><code>ythub.html</code> : Page linking proxied Youtube.</li>
<li><code>ytmobile.html</code> : Page linking to a proxied YouTube for mobile users.</li>
<li><code>chatbox.html</code> : Links to an externally hosted Chatbox.</li>
<li><code>bookmarklets.html</code> : Page for Bookmarklets.<h3 id="structure-information">Structure Information</h3>
</li>
<li><code>/public/</code> : The physical site base of Holy Unblocker goes here. Do not delete or modify <code>/utils</code> as its needed for Alloy.</li>
</ul>
<h4 id="details-of-public-">Details of <code>/public</code></h4>
<ul>
<li><code>/pages/</code> is used for important pages for the site.</li>
<li><code>/expr/</code> is used for important proxy scripts.</li>
<li><code>/archive/</code> and <code>/css</code> is used for game related assets and pages.</li>
<li><code>/assets/</code> is used for various assets for CSS, JS and Bootstrap.</li>
<li><code>/vibeOS/</code> is used for vibeOS, an in-browser OS enviroment.</li>
</ul>
<h4 id="scripts-located-in-expr-">Scripts located in <code>/expr</code></h4>
<ul>
<li><code>[Proxy Initial]bp.js</code> is used for future implementation of Cookie Auth and navigation to external proxies. Must be located in the
<body> tag.</li>
<li><code>[Proxy Initial]load.js</code> is used for initializing the bp script(s). Must be located in the <code>&lt;head&gt;</code> tag.</li>
<li><code>d.html</code> is used for a locally running Discord proxy along with <code>dbp.js</code></li>
</ul>
<h4 id="details-of-auth-js-">Details of <code>auth.js</code></h4>
<ul>
<li>Will be used for the implementation of Cookie Authorization</li>
</ul>
<h2 id="future-additions">Future Additions</h2>
<ul>
<li>Cookie Authorization</li>
<li>Filters</li>
</ul>
<h2 id="vauge-explanation-for-beginners-with-external-and-hosting">Vauge Explanation for Beginners With External Proxies and Hosting</h2>
<p>You will first want to host your proxies locally or externally. </p>
<h4 id="list-of-some-good-hosting-options">List of some good hosting options:</h4>
<ul>
<li><a href="https://heroku.com">Heroku</a> (Free)</li>
<li><a href="https://nodeclusters.com">NodeClusters</a> (Paid)</li>
<li><a href="https://glitch.com">Glitch</a> (Free)</li>
<li><a href="https://repl.it">Repl.it</a> (Free)</li>
<li><a href="https://azure.microsoft.com/en-us/">Azure</a> (Free and Paid)</li>
</ul>
<p>Out of the list of hosting providers Heroku and NodeClusters rank first as a preference. You may also self-host. Currently at this time Azure is used to host the official Holy Unblocker sites.</p>
<p>After you have selected a decent VPS, use Cloudflare for the DNS records for both the site and the subdomains for the proxies.</p>
<p>This is an example of DNS records involving Heroku. Self-hosting will require <code>A records</code> preferably.
<img src="https://cdn.discordapp.com/attachments/725506757291671663/756659513179766844/unknown.png" width="500" height="154"></img></p>
<ul>
<li><code>a.deepsoil.ml</code> is being used for Node Unblocker.</li>
<li><code>p.deepsoil.ml</code> is being used for Powermouse.</li>
<li><code>pd.deepsoil.ml</code> is being used for PyDodge B.</li>
<li><code>cdn.deepsoil.ml</code> is being used for a private Alloy host on the official sites.</li>
</ul>
<p>As stated previously, Holy Unblocker is hosted locally with Alloy.</p>
<h4 id="heroku-steps">Heroku Steps</h4>
<p><strong>So use Heroku to host. I personally favor it as a free choice.</strong> </p>
<ul>
<li>First obtain a card; (Prepaid, Debit, and Credit Cards work). You need this to add custom domains to your Heroku instance.</li>
</ul>
<p>Make sure you connect your Heroku app to your GitHub and enable automatic deploys. Will make things easier. :) </p>
<h4 id="freenom-domain-steps">Freenom/Domain Steps</h4>
<p>For beginners, Freenom is a good provider for obtaining domains for free. However the catch is that you can only use properly &quot;Freenom&quot; domains for free being .cf, .ml, .gq, ga and .tk. However these can be blocked rather easily.</p>
<ul>
<li>Get some Freenom domains then add them to your Heroku instance (Personal &gt; [App Name] &gt; Settings &gt; Domains)
Add a domain for both <code>www.youdomainhere.cf</code> and <code>yourdomainhere.cf</code> with .cf being interchangeable with other Freedom domain names.</li>
<li>If you prefer to obtain premium domains (TLDs) then use <a href="https://porkbun.com">Porkbun</a>, which offers domains for amazing prices. Literally a <code>.net</code> domain normally costs around $10. On Porkbun for the first year it costs $3 so its definitely a deal.</li>
</ul>
<h4 id="cloudflare-steps">Cloudflare Steps</h4>
<ul>
<li>Use Cloudflare (make an account), add your site (Freenom Domain or Domain) and then add your various DNS targets to Cloudflare. Make sure you add Cloudflare&#39;s Nameservers which will be specified more when you are adding your site. </li>
</ul>
<p>Make sure they are CNAME although A records also work and try to follow this structure:</p>
<p><strong>Type | Name | Target</strong></p>
<p><code>CNAME | www | yourherokutargethere.herokudns.com</code>
<code>CNAME | @ | yourherokudnstargethere.herokudns.com</code></p>
<p><strong>Below are if you want external proxies also with your site:</strong></p>
<p><code>CNAME | a | yournodeinstance.herokudns.com</code>
<code>CNAME | pd | yourpydodgebinstancehere.herokudns.com</code>
<code>CNAME | p | yourpowermouseinstancehere.herokudns.com</code></p>
<p>Make sure HTTPS is forced and have SSL set to Flexible for Heroku. Otherwise you can have SSL set to Full.</p>
<h4 id="workspace-configurations">Workspace Configurations</h4>
<p>Preferably if you have your own device use Visual Studio Code. Pretty much the best option you can get but obviously this is an opinion. Also make sure you have <a href="https://nodejs.org/">Node.JS</a> installed on your machine.</p>
<p>Not going to go too in depth with this part but first fork this repository. The clone it locally through a Terminal of some sort depending on what OS you are on. Make sure you navigate to the folder you want to set this up in.</p>
<pre><code>git <span class="hljs-keyword">clone</span> <span class="hljs-title">https</span>://github.com/QuiteAFancyEmerald/HolyUnblockerPublic.git
cd HolyUnblockerPublic
npm install
</code></pre>
<p>Now simply add the folder you cloned this repo in in VSC. Then run <code>npm install</code>. I recommend that if you are releasing this publically on GitHub that you add a <code>.gitignore</code> in your root directory with the following exclusions:</p>
<p><code>node_modules</code></p>
<p>Now you have your following workspace environment setup. To deploy the following workspace you just created you will need to look up depending on your hosting provider.</p>
<p>For an online IDE that you can use on your school computer and/or chromebook use GitPod. Basically the equivalent of Visual Studio Code but with in-browser support.</p>
<ul>
<li>Make an account: <code>https://gitpod.io/</code></li>
<li>Fork this repo and enter in this URL to setup your workspace: <code>https://gitpod.io#https://github.com/YourNameHere/HolyUnblockerPublic/</code></li>
</ul>
<p>Use the same steps above by running <code>npm install</code> in your repository and adding a <code>.gitignore</code> in your root directory specifying to exclude <code>node_modules</code>.</p>
<h2 id="more-information">More Information</h2>
<p>This project uses Alloy Proxy, Node Unblocker, Powermouse and PyDodge which are linked below. Credits also given to Titanium Network and all it&#39;s developers as this project would not be possible without them. View the official website for more detail. :)</p>
<ul>
<li><a href="https://github.com/titaniumnetwork-dev/">https://github.com/titaniumnetwork-dev/</a></li>
<li><a href="https://github.com/titaniumnetwork-dev/alloyproxy">https://github.com/titaniumnetwork-dev/alloyproxy</a></li>
<li><a href="https://github.com/nfriedly/node-unblocker">https://github.com/nfriedly/node-unblocker</a></li>
<li><a href="https://github.com/vibedivide/powermouse">https://github.com/vibedivide/powermouse</a></li>
<li><a href="https://github.com/BinBashBanana/PyDodge">https://github.com/BinBashBanana/PyDodge</a></li>
<li><a href="https://github.com/juchi/gameboy.js">https://github.com/juchi/gameboy.js</a></li>
<li><a href="https://nodeclusters.com">https://nodeclusters.com</a></li>
<li><a href="https://titaniumnetwork.org/">https://titaniumnetwork.org/</a></li>
<li><a href="https://github.com/vibedivide/vibeOS">https://github.com/vibedivide/vibeOS</a></li>
</ul>
<p>Thanks.</p>
</div>
</div>
</body>
<html>

View file

@ -1,8 +0,0 @@
window.onload = function() {
var frame = document.getElementById("frame");
var det = document.domain;
var domain = det.replace('www.', '').split(/[/?#]/)[0];
frame.src = "https://c." + domain + "/app";
document.cookie = 'oldsmobile=badcar; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + auth + '; path=/; Secure;';
return false;
};

View file

@ -1,16 +0,0 @@
window.onload = function() {
var url = `https://discord.com/login`;
var det = document.domain;
var domain = det.replace('www.', '').split(/[/?#]/)[0];
const origin = btoa(url)
window.location.href = "https://" + domain + "/fetch/utils/?url=" + origin;
document.cookie = '__alloy_cookie_auth=yes; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + auth + '; path=/; Secure;';
return false;
};
// Cookie Auth
var host = location.hostname.split('.');
var auth = location.hostname;
if (host.length == 3) {
auth = `${host[1]}.${host[2]}`;
}

View file

@ -1,3 +1,8 @@
/* -----------------------------------------------
/* MIT license: http://opensource.org/licenses/MIT
/* How to use? : Check the documentation. Button ID attributes are used for the script below.
/* v2.0.0
/* ----------------------------------------------- */
$ = e => document.getElementById(e) || []; $ = e => document.getElementById(e) || [];
//AL //AL
@ -128,15 +133,6 @@ $('ytbp').onclick = function() {
document.cookie = 'oldsmobile=badcar; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + auth + '; path=/; Secure;'; document.cookie = 'oldsmobile=badcar; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + auth + '; path=/; Secure;';
return false; return false;
}; };
$('chat').onclick = function() {
var frame = document.getElementById("frame");
var det = document.domain;
var domain = det.replace('www.', '').split(/[/?#]/)[0];
frame.src = "https://c." + domain + "/app";
frame.style['visibility'] = "visible";
document.cookie = 'oldsmobile=badcar; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + auth + '; path=/; Secure;';
return false;
};
//D //D
$('dbtn').onclick = function() { $('dbtn').onclick = function() {
var frame = document.getElementById("frame"); var frame = document.getElementById("frame");

View file

@ -1,15 +0,0 @@
window.onload = function() {
// similar behavior as an HTTP redirect
var yt = `https://youtube.com`;
var det = document.domain;
var domain = det.replace('www.', '').split(/[/?#]/)[0];
const origin = btoa(yt);
window.location.replace("https://" + domain + "/fetch/utils/?url=" + origin);
document.cookie = '__alloy_cookie_auth=yes; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + auth + '; path=/; Secure;';
}
// Cookie Auth
var host = location.hostname.split('.');
var auth = location.hostname;
if (host.length == 3) {
auth = `${host[1]}.${host[2]}`;
}

View file

@ -1,15 +0,0 @@
window.onload = function() {
// similar behavior as an HTTP redirect
var yt = `https://m.youtube.com`;
var det = document.domain;
var domain = det.replace('www.', '').split(/[/?#]/)[0];
const origin = btoa(yt);
window.location.replace("https://" + domain + "/fetch/utils/?url=" + origin);
document.cookie = '__alloy_cookie_auth=yes; expires=' + (Date.now() + 259200) + '; SameSite=Lax; domain=.' + auth + '; path=/; Secure;';
}
// Cookie Auth
var host = location.hostname.split('.');
var auth = location.hostname;
if (host.length == 3) {
auth = `${host[1]}.${host[2]}`;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -17,7 +17,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -26,13 +26,12 @@
</head> </head>
<body> <body>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<!-- Important: Use <wbr> to mess with keywords. --> <!-- Important: Use <wbr> to mess with keywords. -->
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">
<nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px; z-index: 1;"> <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px; z-index: 1;">
<div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" <div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1"> <div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto"> <ul class="nav navbar-nav ml-auto">
<!--Nav--> <!--Nav-->
@ -42,8 +41,7 @@
<li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li> <li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li>
<li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li> <li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li>
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a>
<div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" <div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
</li> </li>
<!--Options Menu--> <!--Options Menu-->
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a>
@ -158,7 +156,6 @@
<script src="assets/js/jquery.min.js"></script> <script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js "></script> <script src="assets/js/bs-init.js "></script>
<script src="expr/surf.js"></script>
</body> </body>
</html> </html>

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -27,13 +27,12 @@
</head> </head>
<body> <body>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<!-- Important: Use <wbr> to mess with keywords. --> <!-- Important: Use <wbr> to mess with keywords. -->
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">
<nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;"> <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;">
<div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" <div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1"> <div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto"> <ul class="nav navbar-nav ml-auto">
<!--Nav--> <!--Nav-->
@ -43,8 +42,7 @@
<li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li> <li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li>
<li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li> <li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li>
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a>
<div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" <div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
</li> </li>
<!--Options Menu--> <!--Options Menu-->
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a>
@ -103,13 +101,12 @@
<h1 class="text-center d-md-flex flex-grow-1 justify-content-md-center align-items-md-center" style="color: rgb(242,245,248);font-size: 46px;font-weight: normal;font-family: 'Montserrat Alternates', sans-serif;margin: 7px;padding: 34px;width: 100%;filter: blur(0px);height: 100%;">Credits<br></h1> <h1 class="text-center d-md-flex flex-grow-1 justify-content-md-center align-items-md-center" style="color: rgb(242,245,248);font-size: 46px;font-weight: normal;font-family: 'Montserrat Alternates', sans-serif;margin: 7px;padding: 34px;width: 100%;filter: blur(0px);height: 100%;">Credits<br></h1>
<p><br>&nbsp;Quite A Fa&#8203;ncy Em&#8203;erald (Crea&#8203;tor and Ow&#8203;ner, Disco&#8203;rd: Quite A Fan&#8203;cy Emer&#8203;ald#0001)<br><br><strong></strong><br>Contributors:<br> Kin&#8203;glalu (Gam&#8203;es Page, <p><br>&nbsp;Quite A Fa&#8203;ncy Em&#8203;erald (Crea&#8203;tor and Ow&#8203;ner, Disco&#8203;rd: Quite A Fan&#8203;cy Emer&#8203;ald#0001)<br><br><strong></strong><br>Contributors:<br> Kin&#8203;glalu (Gam&#8203;es Page,
Developer) Developer)
<br><strong> O&#8203;lyB (Tab Cl&#8203;oak, Web Developer)</strong><br><strong>&nbsp;YOCTDON&#8203;ALD'S (Obfusc&#8203;ation God, T&#8203;N Bugh&#8203;unter)</strong><br><strong> SexyDuceDuce (Pr&#8203;oxy and Web Dev&#8203;eloper)</strong><br><strong></strong><br>Notable <br><strong> O&#8203;lyB (Tab Cl&#8203;oak, Web Developer)</strong><br><strong>&nbsp;YOCTDON&#8203;ALD'S (Obfusc&#8203;ation God, T&#8203;N Bugh&#8203;unter)</strong><br><strong> SexyDuceDuce (Pr&#8203;oxy and Web Dev&#8203;eloper)</strong><br><strong></strong><br>Notable Mentions:
Mentions:
<br> LQ16 (Creator of TN, Retired)</strong><br>Shirt (Owner of TN)<br> Mik<wbr>eLime (<strong>Co-Owner of Tit<wbr>anium<wbr>Ne<wbr>twork &amp; Mass Pr<wbr>o<wbr>xy Site Maker, Web Deve&#8203;loper, and Software Developer</strong>) <br> LQ16 (Creator of TN, Retired)</strong><br>Shirt (Owner of TN)<br> Mik<wbr>eLime (<strong>Co-Owner of Tit<wbr>anium<wbr>Ne<wbr>twork &amp; Mass Pr<wbr>o<wbr>xy Site Maker, Web Deve&#8203;loper, and Software Developer</strong>)
:D :D
<br> Sou&#8203;p (Cat La&#8203;dy) hehe<br> <br> Sou&#8203;p (Cat La&#8203;dy) hehe<br>
<br><strong> Na<wbr>vvy</strong><br><strong>- Divi&#8203;de (Chatb&#8203;ox, Pro&#8203;xy/W&#8203;eb Deve&#8203;loper)<br><strong> B<wbr>3A<wbr>TDR<wbr>O<wbr>P3R</strong><br> Nautica<br><strong><br><strong></strong><br>And <br><strong> Na<wbr>vvy</strong><br><strong>- Divi&#8203;de (Chatb&#8203;ox, Pro&#8203;xy/W&#8203;eb Deve&#8203;loper)<br><strong> B<wbr>3A<wbr>TDR<wbr>O<wbr>P3R</strong><br> Nautica<br><strong><br><strong></strong><br>And
everyone else on TN and to the various testers. :D<br><br>And of course a certain Michael (irl friend)<br><br></p> everyone else on TN and to the various testers. :D<br><br>And of course a certain Michael (irl friend)<br><br></p>div>
</div> </div>
</div> </div>
</div> </div>
@ -156,7 +153,6 @@
<script src="assets/js/links.js"></script> <script src="assets/js/links.js"></script>
<script src="assets/js/jquery.min.js"></script> <script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="expr/surf.js"></script>
</body> </body>
</html> </html>

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -28,13 +28,12 @@
</head> </head>
<body> <body>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<!-- Important: Use <wbr> to mess with keywords. --> <!-- Important: Use <wbr> to mess with keywords. -->
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">
<nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;"> <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;">
<div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" <div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1"> <div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto"> <ul class="nav navbar-nav ml-auto">
<!--Nav--> <!--Nav-->
@ -44,8 +43,7 @@
<li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li> <li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li>
<li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li> <li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li>
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a>
<div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" <div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
</li> </li>
<!--Options Menu--> <!--Options Menu-->
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a>
@ -279,7 +277,6 @@
<script src="assets/js/links.js"></script> <script src="assets/js/links.js"></script>
<script src="assets/js/jquery.min.js"></script> <script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="expr/surf.js"></script>
</body> </body>
</html> </html>

View file

@ -17,7 +17,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -28,11 +28,10 @@
<!--Games Old CSS --> <!--Games Old CSS -->
<body> <body>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">
<nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;"> <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;">
<div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" <div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1"> <div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto"> <ul class="nav navbar-nav ml-auto">
<!--Nav--> <!--Nav-->
@ -56,8 +55,7 @@
<li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li> <li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li>
<li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li> <li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li>
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a>
<div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" <div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
</li> </li>
<!--Options Menu--> <!--Options Menu-->
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a>
@ -470,7 +468,6 @@
<script src="assets/js/links.js"></script> <script src="assets/js/links.js"></script>
<script src="assets/js/jquery.min.js"></script> <script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="expr/surf.js"></script>
</body> </body>
</html> </html>

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -28,13 +28,11 @@
</head> </head>
<body> <body>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<!--New-->
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">
<nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;"> <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;">
<div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" <div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1"> <div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto"> <ul class="nav navbar-nav ml-auto">
<!--Nav--> <!--Nav-->
@ -44,8 +42,7 @@
<li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li> <li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li>
<li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li> <li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li>
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a>
<div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" <div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
</li> </li>
<!--Options Menu--> <!--Options Menu-->
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a>
@ -167,7 +164,6 @@
<script src="assets/js/jquery.min.js"></script> <script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/bs-init.js"></script> <script src="assets/js/bs-init.js"></script>
<script src="expr/surf.js"></script>
</body> </body>
</html> </html>

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -27,13 +27,12 @@
</head> </head>
<body> <body>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<!-- Important: Use <wbr> to mess with keywords. --> <!-- Important: Use <wbr> to mess with keywords. -->
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">
<nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;"> <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;">
<div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" <div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1"> <div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto"> <ul class="nav navbar-nav ml-auto">
<!--Nav--> <!--Nav-->
@ -43,8 +42,7 @@
<li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li> <li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li>
<li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li> <li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li>
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a>
<div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" <div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
</li> </li>
<!--Options Menu--> <!--Options Menu-->
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a>
@ -160,7 +158,6 @@
<script src="assets/js/links.js"></script> <script src="assets/js/links.js"></script>
<script src="assets/js/jquery.min.js"></script> <script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="expr/surf.js"></script>
</body> </body>
</html> </html>

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -29,13 +29,13 @@
</head> </head>
<body> <body>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<!-- Important: Use <wbr> to mess with keywords. --> <!-- Important: Use <wbr> to mess with keywords. -->
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">
<nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;"> <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;">
<div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" <div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1"> <div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto"> <ul class="nav navbar-nav ml-auto">
<!--Nav--> <!--Nav-->
@ -45,8 +45,7 @@
<li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li> <li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li>
<li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li> <li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li>
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a>
<div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" <div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
</li> </li>
<!--Options Menu--> <!--Options Menu-->
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a>
@ -78,8 +77,7 @@
<!-- Particles.js background --> <!-- Particles.js background -->
<script id="particles-js" style="background-image: url(&quot;assets/img/black.jpg&quot;);height: 100%;background-position: center;background-size: cover;background-repeat: no-repeat;background-color: #000000;font-family: 'Montserrat Alternates', sans-serif;font-weight: bold;" <script id="particles-js" style="background-image: url(&quot;assets/img/black.jpg&quot;);height: 100%;background-position: center;background-size: cover;background-repeat: no-repeat;background-color: #000000;font-family: 'Montserrat Alternates', sans-serif;font-weight: bold;" /> document.write(`
/> document.write(`
<div> <div>
<h1>Privacy Policy for Holy Unblocker</h1> <h1>Privacy Policy for Holy Unblocker</h1>
@ -345,7 +343,6 @@
<script src="assets/js/links.js"></script> <script src="assets/js/links.js"></script>
<script src="assets/js/jquery.min.js"></script> <script src="assets/js/jquery.min.js"></script>
<script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="expr/surf.js"></script>
</body> </body>
</html> </html>

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -27,6 +27,8 @@
</head> </head>
<body> <body>
<span style=display:none data-cooking=cooks>Cuisines Often, a certain combination of ingredients forms the foundation of a particular cuisine. For example, Cantonese cuisine, based in southern China, makes much use of scallions, garlic, and ginger. Greek dishes often include garlic, olive oil, and oregano. Cuisines are often based on locally available ingredients. In the coastal city of Boston, for example, traditional favorites include such seafood dishes as clam chowder and lobster. Many cuisines reflect the variety of cultures in an area. In Louisiana, for example, such dishes as gumbo (a spicy stew) combine African American, Native American, and French cooking traditions. Preparation of ingredients Many ingredients must be prepared before cooking. Some fruits and vegetables must be peeled. Cooks may remove the skin, bones, and fat from meat or the shells from seafood. Cooks may also cut ingredients in a variety of ways, including dicing (cutting into small cubes) and mincing (chopping extremely fine). The size of the pieces helps determine how fast they cook, as well as the texture of the finished dish. Many cooks season food with salt, spices, and herbs before cooking. Ingredients must be prepared with safety in mind. Fruits and vegetables should generally be rinsed to remove any residues from agricultural chemicals. In addition, raw meats may contain disease-causing organisms. Proper cooking usually kills such organisms. But anything the meat touches can also become contaminated. Cooks must thus be careful when handling raw meat. They can help prevent food-borne illness by using soap and hot water to wash their hands, along with any surface that has touched raw meat.
</span>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <iframe id="frame" style="display:block; visibility: hidden;"></iframe>
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">
@ -99,20 +101,6 @@
<p class="text-white s-text-p2"><br>All<wbr>oy Pr<wbr>ox<wbr>y created by S<wbr>exyDu<wbr>ceD<wbr>uce <p class="text-white s-text-p2"><br>All<wbr>oy Pr<wbr>ox<wbr>y created by S<wbr>exyDu<wbr>ceD<wbr>uce
(a very epic person) :D<br>All<wbr>oy v2.3</p> (a very epic person) :D<br>All<wbr>oy v2.3</p>
</form> </form>
<span style=display:none data-cooking=cooks>Cooking started 1.9 million years ago. Therefore, cooking is not something new to humans. Cooking started over a fire with no pots and pans or cooking utensils and now we have microwaves and stoves and special brushes to wipe on a marinade which was not even able to be comprehended 1.9 years ago. In between that time was the middle ages which had many advancements. Life was very different before cooking and has been very different since the beginning of cooking.
1.9 million years ago, given humans average sizes, had to spend forty eight percent of their life time in the “feeding process.” The feeding process does not include cooking. Cooking narrowed the time that humans had to spend in the feeding process to five percent. This change made it to where humans could spend less time in the feeding process and could do more valuable things with their time such as go out and hunt to grow bigger societies and other pursuits which ultimately lead to the beginning to the path of our modern brain. Cooking made food a lot easier to chew and digest. As a result of that we got more calorie benefit and a smaller digestive tract. All of this made cooking a vital part of human adaptation. The changes in human teeth happened so much faster than anything in the human body that scientists have come to the conclusion that this means that cooking was and has been passed down from generations and generations. Also, the oppressed women theory has been going on since the beginning of cooking when men went out and hunted and sought new things. Women at this time had to cook and do the gathering because of their lack of physically strength. So ever since cooking, even 1.9 million years ago, the roles of men and women have been a natural thing of life...
... middle of paper ...
...still be spending too much time eating and cooking. Different things in nature such as wood, spices, iron and chemicals that make up fire, which are just a few, helped start and continue cooking down the path that its going down. I think that cooking will continue to expand as technology advances. I am not sure how it will advance and change but I am sure we will have better more efficient stove tops and ovens.
In conclusion, cooking has evolved as technology has developed. But in the grand scheme of things we still have the same methods. Cooking helped the advancement of the human brain and the advancement of human teeth and our digestive tracts. Today we have restaurants, grocery stores, microwaves, and ovens. And all we started off with was a fire and a piece of meat with a stick stuck through it. Cooking was, is, and will be a vital part of the human life.
</span>
</div> </div>
</div> </div>
</div> </div>

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/fonts/ionicons.min.css"> <link rel="stylesheet" href="assets/fonts/ionicons.min.css">
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -27,6 +27,7 @@
</head> </head>
<body> <body>
<span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <iframe id="frame" style="display:block; visibility: hidden;"></iframe>
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -27,6 +27,7 @@
</head> </head>
<body> <body>
<span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <iframe id="frame" style="display:block; visibility: hidden;"></iframe>
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -27,6 +27,7 @@
</head> </head>
<body> <body>
<span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<iframe id="frame" style="visibility: hidden;"></iframe> <iframe id="frame" style="visibility: hidden;"></iframe>
<noscript>You must enable javascript in your browser to view this webpage.</noscript> <noscript>You must enable javascript in your browser to view this webpage.</noscript>
<!--New--> <!--New-->

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -27,6 +27,7 @@
</head> </head>
<body> <body>
<span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <iframe id="frame" style="display:block; visibility: hidden;"></iframe>
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -27,6 +27,7 @@
</head> </head>
<body> <body>
<span style=display:none data-cooking=cooks>Methods Heat can transform the flavor and texture of ingredients. Browning meat and other ingredients, for example, involves complex chemical reactions. Fruits and vegetables contain sugars that caramelize when browned. The reaction in browning proteins, such as those in meat and poultry, is called the Maillard reaction after Louis Camille Maillard, the French chemist who discovered it. The Maillard reaction produces many new chemical compounds. These compounds give the food new flavors and aromas. The browned bits of food that stick to a pan are called fond, a French word meaning bottom. Many sauces make use of the rich, complex flavors of fond. Browning can only occur at temperatures above the boiling point of water, which is 212 °F (100 °C) at sea level. For this reason, moisture around the exterior of food must evaporate before the food can brown. Air and fat, as well as the metal surfaces of pans, can reach extremely high temperatures in browning. But cooking ingredients at high temperature for too long removes moisture, turning food dry and chewy. Skilled cooks will therefore carefully control both heat and moisture when cooking. Cooking with dry heat involves exposing food to hot air. As the air moves around the foods surface, its heat is transferred to the cooler food. Roasting traditionally involved cooking large pieces of meat—or even a whole animal, such as a pig or a lamb—over an open fire. But today, roasting generally refers to cooking food in a hot oven. Roasting meat or vegetables in a high temperature oven—above 400 °F (205 °C)—causes the food to brown quickly. But high temperatures can also dry out food. Cooks thus sometimes brown meat and then finish it in a lower temperature oven to keep it moist inside. Cooks often roast ingredients on a rack above a roasting pan, enabling hot air to reach all sides of the food.</span>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <iframe id="frame" style="display:block; visibility: hidden;"></iframe>
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">

View file

@ -11,13 +11,21 @@
:D"> :D">
<link rel="icon" type="image/png" sizes="32x32" href="assets/img/i.png"> <link rel="icon" type="image/png" sizes="32x32" href="assets/img/i.png">
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<style type="text/css">
body,
html {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
}
</style>
<!-- AL YT --> <!-- AL YT -->
<script src="/expr/ch.js"></script> <script src="/expr/ch.js"></script>
<script async src="https://arc.io/widget.js#2BzvQ1em"></script> <script async src="https://arc.io/widget.js#2BzvQ1em"></script>
</head> </head>
<body> <body>
<iframe id="frame" style="visibility: visible;"></iframe>
<span style=display:none data-cooking=cooks>Cooking started 1.9 million years ago. Therefore, cooking is not something new to humans. Cooking started over a fire with no pots and pans or cooking utensils and now we have microwaves and stoves and special brushes to wipe on a marinade which was not even able to be comprehended 1.9 years ago. In between that time was the middle ages which had many advancements. Life was very different before cooking and has been very different since the beginning of cooking. <span style=display:none data-cooking=cooks>Cooking started 1.9 million years ago. Therefore, cooking is not something new to humans. Cooking started over a fire with no pots and pans or cooking utensils and now we have microwaves and stoves and special brushes to wipe on a marinade which was not even able to be comprehended 1.9 years ago. In between that time was the middle ages which had many advancements. Life was very different before cooking and has been very different since the beginning of cooking.
1.9 million years ago, given humans average sizes, had to spend forty eight percent of their life time in the “feeding process.” The feeding process does not include cooking. Cooking narrowed the time that humans had to spend in the feeding process to five percent. This change made it to where humans could spend less time in the feeding process and could do more valuable things with their time such as go out and hunt to grow bigger societies and other pursuits which ultimately lead to the beginning to the path of our modern brain. Cooking made food a lot easier to chew and digest. As a result of that we got more calorie benefit and a smaller digestive tract. All of this made cooking a vital part of human adaptation. The changes in human teeth happened so much faster than anything in the human body that scientists have come to the conclusion that this means that cooking was and has been passed down from generations and generations. Also, the oppressed women theory has been going on since the beginning of cooking when men went out and hunted and sought new things. Women at this time had to cook and do the gathering because of their lack of physically strength. So ever since cooking, even 1.9 million years ago, the roles of men and women have been a natural thing of life... 1.9 million years ago, given humans average sizes, had to spend forty eight percent of their life time in the “feeding process.” The feeding process does not include cooking. Cooking narrowed the time that humans had to spend in the feeding process to five percent. This change made it to where humans could spend less time in the feeding process and could do more valuable things with their time such as go out and hunt to grow bigger societies and other pursuits which ultimately lead to the beginning to the path of our modern brain. Cooking made food a lot easier to chew and digest. As a result of that we got more calorie benefit and a smaller digestive tract. All of this made cooking a vital part of human adaptation. The changes in human teeth happened so much faster than anything in the human body that scientists have come to the conclusion that this means that cooking was and has been passed down from generations and generations. Also, the oppressed women theory has been going on since the beginning of cooking when men went out and hunted and sought new things. Women at this time had to cook and do the gathering because of their lack of physically strength. So ever since cooking, even 1.9 million years ago, the roles of men and women have been a natural thing of life...

View file

@ -18,7 +18,7 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<link rel="stylesheet" href="assets/css/styles.css"> <link rel="stylesheet" href="assets/css/styles.css">
<!-- Assets --> <!-- Assets -->
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script> <script src="particles.js"></script>
<script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script> <script type="module" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script> <script nomodule="" src="https://unpkg.com/ionicons@5.1.2/dist/ionicons/ionicons.js"></script>
<script src="assets/js/header.js"></script> <script src="assets/js/header.js"></script>
@ -27,12 +27,11 @@
</head> </head>
<body> <body>
<iframe id="frame" style="display:block; visibility: hidden;"></iframe> <!--New-->
<div> <div>
<div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);"> <div class="header-dark" style="background-color: rgb(0,0,0);background-image: url(&quot;assets/img/black.jpg&quot;);">
<nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;"> <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search" style="height: 100px;">
<div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" <div class="container"><a class="navbar-brand" style="font-family: 'Montserrat Alternates', sans-serif;font-size: 21px;margin: 10px;font-style: normal;font-weight: bold;" href="/">Ho&#8203;ly Unb&#8203;lock&#8203;er</a><button data-toggle="collapse" class="navbar-toggler" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navcol-1"> <div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav ml-auto"> <ul class="nav navbar-nav ml-auto">
<!--Nav--> <!--Nav-->
@ -42,8 +41,7 @@
<li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li> <li class="nav-item" role="presentation"><a class="nav-link" href="/?d" style="font-family: 'Montserrat Alternates', sans-serif;">D&#8203;isc&#8203;ord</a></li>
<li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li> <li id="ch" class="nav-item" role="presentation"><a class="nav-link" href="/?n" style="font-family: 'Montserrat Alternates', sans-serif;">Cha&#8203;tbox</a></li>
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;color: rgb(255,255,255);font-family: 'Montserrat Alternates', sans-serif;">More</a>
<div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" <div class="dropdown-menu" role="menu" style="background-color: rgb(33,30,30);font-family: 'Titillium Web', sans-serif;padding: 17%;padding-top: 10%;padding-bottom: 10%;"><a class="dropdown-item text-left text-white-50" role="presentation" href="/?k" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Kru&#8203;nk&#8203;er</a><a class="dropdown-item text-left text-white-50" role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
role="presentation" href="/?in" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Docs</a><a class="dropdown-item text-white-50" role="presentation" href="/?c" style="color: rgb(255,255,255);padding: 0%;font-family: Lato, sans-serif;">Cre&#8203;dits</a></div>
</li> </li>
<!--Options Menu--> <!--Options Menu-->
<li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a> <li class="nav-item dropdown"><a class="dropdown-toggle nav-link text-white" data-toggle="dropdown" aria-expanded="false" href="#" style="opacity: 0.80;font-family: 'Montserrat Alternates', sans-serif;">Options</a>
@ -89,17 +87,17 @@
<p class="s-text-header" style="font-size: 46px;">Su<wbr>rf Free<wbr>ly</p> <p class="s-text-header" style="font-size: 46px;">Su<wbr>rf Free<wbr>ly</p>
<p class="s-text-p1" style="font-family: 'Montserrat Alternates', sans-serif;">Choose which proxy you would like to use. Below is some information.</p> <p class="s-text-p1" style="font-family: 'Montserrat Alternates', sans-serif;">Choose which proxy you would like to use. Below is some information.</p>
<p class="text-white" style="font-size: 20px;font-family: Lato, sans-serif;">More Information:<br></p> <p class="text-white" style="font-size: 20px;font-family: Lato, sans-serif;">More Information:<br></p>
<p class="text-hb-light s-text-p2" style="font-family: Lato, sans-serif;">A&#8203;llo&#8203;y: Di&#8203;sco&#8203;rd (Mostly Full), Yo&#8203;uTu&#8203;be (Full), etc.<br><br>Vi<wbr>a: Alter<wbr>native pro<wbr>xy which suppo<wbr>rts many ga<wbr>me si<wbr>tes, etc.<br><br>Nod&#8203;e: Secondary <p class="text-hb-light s-text-p2" style="font-family: Lato, sans-serif;">A&#8203;llo&#8203;y: Di&#8203;sco&#8203;rd (Mostly Full), Yo&#8203;uTu&#8203;be (Full), etc.<br><br>Vi<wbr>a: Alter<wbr>native pro<wbr>xy which suppo<wbr>rts many ga<wbr>me si<wbr>tes, etc.<br><br>Nod&#8203;e: Secondary pr&#8203;oxy compared to Al&#8203;loy, PM and PD.<br><br>P<wbr>M Pro<wbr>xy: Disc<wbr>ord, Yout<wbr>ube
pr&#8203;oxy compared to Al&#8203;loy, PM and PD.<br><br>P<wbr>M Pro<wbr>xy: Disc<wbr>ord, Yout<wbr>ube (limited), etc.<br> (limited), etc.<br>
</p> </p>
<p class="text-white s-text-p2">Many sites work with this. Join the T<wbr>N disc<wbr>ord for updated H<wbr>B sites and more. Explore!</strong><br>T<wbr>N D<wbr>isco<wbr>rd:</p> <p class="text-white s-text-p2">Many sites work with this. Join the T<wbr>N disc<wbr>ord for updated H<wbr>B sites and more. Explore!</strong><br>T<wbr>N D<wbr>isco<wbr>rd:</p>
<a class="text-hb s-text-p2" id="tnlink">https://dis&#8203;cord.c&#8203;om/invite/Dw&#8203;6C7p&#8203;5</a><br> <a class="text-hb s-text-p2" id="tnlink">https://dis&#8203;cord.c&#8203;om/invite/Dw&#8203;6C7p&#8203;5</a><br>
<div style="margin: 2%;padding: 1px;"> <div style="margin: 2%;padding: 1px;">
<a class="btn btn-group text-hb hb-border-color glow-on-hover rounded-1" role="button" data-bs-hover-animate="pulse" style="background-color: rgb(24,26,28);font-family: 'Montserrat Alternates', sans-serif;" href="/?a">Al<wbr>loy Pro<wbr>xy</a> <a class="btn btn-group text-hb hb-border-color glow-on-hover rounded-1" role="button" data-bs-hover-animate="pulse" style="background-color: rgb(24,26,28);font-family: 'Montserrat Alternates', sans-serif;" href="/?a">Al<wbr>loy Pro<wbr>xy</a>
<a class="btn btn-group text-hb hb-border-color glow-on-hover rounded-1" role="button" data-bs-hover-animate="pulse" style="background-color: rgb(24,26,28);font-family: 'Montserrat Alternates', sans-serif; margin-left: 5px;" href="/?e">V<wbr>ia Un<wbr>blo<wbr>cker</a> <a class="btn btn-group text-hb hb-border-color glow-on-hover rounded-1" role="button" data-bs-hover-animate="pulse" style="background-color: rgb(24,26,28);font-family: 'Montserrat Alternates', sans-serif; margin-left: 5px;" href="/?e">V<wbr>ia Un<wbr>blo<wbr>cker</a>
<a class="btn btn-group text-hb hb-border-color glow-on-hover rounded-1" role="button" data-bs-hover-animate="pulse" style="background-color: rgb(24,26,28);font-family: 'Montserrat Alternates', sans-serif; margin-left: 5px;" href="/?b">No<wbr>de Un<wbr>bloc<wbr>ker</a> <a class="btn btn-group text-hb hb-border-color glow-on-hover rounded-1" role="button" data-bs-hover-animate="pulse" style="background-color: rgb(24,26,28);font-family: 'Montserrat Alternates', sans-serif; margin-left: 5px;" href="/?b">No<wbr>de Un<wbr>bloc<wbr>ker</a>
<a class="btn btn-group text-hb hb-border-color glow-on-hover rounded-1 " role="button" data-bs-hover-animate="pulse" style="background-color: rgb(24,26,28);font-family: 'Montserrat Alternates', sans-serif; margin-left: 5px; " href="/?p">PM Pro<wbr>xy</a> <a class="btn btn-group text-hb hb-border-color glow-on-hover rounded-1 " role="button" data-bs-hover-animate="pulse" style="background-color: rgb(24,26,28);font-family: 'Montserrat Alternates', sans-serif; margin-left: 5px; " href="/?p">PM Pro<wbr>xy</a>
</div> </div>
<span style=display:none data-cooking=cooks>Cooking started 1.9 million years ago. Therefore, cooking is not something new to humans. Cooking started over a fire with no pots and pans or cooking utensils and now we have microwaves and stoves and special brushes to wipe on a marinade which was not even able to be comprehended 1.9 years ago. In between that time was the middle ages which had many advancements. Life was very different before cooking and has been very different since the beginning of cooking. <span style=display:none data-cooking=cooks>Cooking started 1.9 million years ago. Therefore, cooking is not something new to humans. Cooking started over a fire with no pots and pans or cooking utensils and now we have microwaves and stoves and special brushes to wipe on a marinade which was not even able to be comprehended 1.9 years ago. In between that time was the middle ages which had many advancements. Life was very different before cooking and has been very different since the beginning of cooking.

1541
public/particles.js Normal file

File diff suppressed because it is too large Load diff

View file

@ -2,31 +2,3 @@ User-agent: *
Allow: / Allow: /
Sitemap: https://quiteafancyemerald.com Sitemap: https://quiteafancyemerald.com
Sitemap: https://holyubofficial.net Sitemap: https://holyubofficial.net
User-agent: Googlebot
Allow: /
Sitemap: https://quiteafancyemerald.com
Sitemap: https://holyubofficial.net
User-agent: DuckDuckBot
Allow: /
Sitemap: https://quiteafancyemerald.com
Sitemap: https://holyubofficial.net
User-agent: Bingbot
Allow: /
Sitemap: https://quiteafancyemerald.com
Sitemap: https://holyubofficial.net
User-agent: Slurp
Allow: /
Sitemap: https://quiteafancyemerald.com
Sitemap: https://holyubofficial.net
User-agent: Baiduspider
Allow: /
Sitemap: https://quiteafancyemerald.com
Sitemap: https://holyubofficial.net

View file

@ -2,122 +2,62 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url> <url>
<loc>https://quiteafancyemerald.com/?a</loc> <loc>https://quiteafancyemerald.com/?a</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://quiteafancyemerald.com/?b</loc> <loc>https://quiteafancyemerald.com/?b</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://quiteafancyemerald.com/?z</loc> <loc>https://quiteafancyemerald.com/?z</loc>
<changefreq>daily</changefreq>
<lastmod>2020-11-11</lastmod>
<priority>0.9<priority>
</url> </url>
<url> <url>
<loc>https://quiteafancyemerald.com/?y</loc> <loc>https://quiteafancyemerald.com/?y</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://quiteafancyemerald.com/?d</loc> <loc>https://quiteafancyemerald.com/?d</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://quiteafancyemerald.com/</loc> <loc>https://quiteafancyemerald.com/</loc>
<changefreq>daily</changefreq>
<lastmod>2020-11-11</lastmod>
<priority>0.9<priority>
</url> </url>
<url> <url>
<loc>https://quiteafancyemerald.com/?k</loc> <loc>https://quiteafancyemerald.com/?k</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://quiteafancyemerald.com/?g</loc> <loc>https://quiteafancyemerald.com/?g</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://quiteafancyemerald.com/?e</loc> <loc>https://quiteafancyemerald.com/?e</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://quiteafancyemerald.com/?in</loc> <loc>https://quiteafancyemerald.com/?in</loc>
<changefreq>daily</changefreq>
<priority>0.9<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/?a</loc> <loc>https://holyubofficial.net/?a</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/?b</loc> <loc>https://holyubofficial.net/?b</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/?z</loc> <loc>https://holyubofficial.net/?z</loc>
<changefreq>daily</changefreq>
<priority>0.9<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/?y</loc> <loc>https://holyubofficial.net/?y</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/?d</loc> <loc>https://holyubofficial.net/?d</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/</loc> <loc>https://holyubofficial.net/</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/?k</loc> <loc>https://holyubofficial.net/?k</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/?g</loc> <loc>https://holyubofficial.net/?g</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/?e</loc> <loc>https://holyubofficial.net/?e</loc>
<changefreq>daily</changefreq>
<priority>0.8<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
<url> <url>
<loc>https://holyubofficial.net/?in</loc> <loc>https://holyubofficial.net/?in</loc>
<changefreq>daily</changefreq>
<priority>0.9<priority>
<lastmod>2020-11-11</lastmod>
</url> </url>
</urlset> </urlset>

View file

@ -1,232 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// CPU class
var CPU = function(gameboy) {
this.gameboy = gameboy;
this.r = {A:0, F: 0, B:0, C:0, D:0, E:0, H:0, L:0, pc:0, sp:0};
this.IME = true;
this.clock = {c: 0, serial: 0};
this.isHalted = false;
this.isPaused = false;
this.usingBootRom = false;
this.createDevices();
};
CPU.INTERRUPTS = {
VBLANK: 0,
LCDC: 1,
TIMER: 2,
SERIAL: 3,
HILO: 4
};
CPU.interruptRoutines = {
0: function(p){GameboyJS.cpuOps.RSTn(p, 0x40);},
1: function(p){GameboyJS.cpuOps.RSTn(p, 0x48);},
2: function(p){GameboyJS.cpuOps.RSTn(p, 0x50);},
3: function(p){GameboyJS.cpuOps.RSTn(p, 0x58);},
4: function(p){GameboyJS.cpuOps.RSTn(p, 0x60);}
};
CPU.prototype.createDevices = function() {
this.memory = new GameboyJS.Memory(this);
this.timer = new GameboyJS.Timer(this, this.memory);
this.apu = new GameboyJS.APU(this.memory);
this.SERIAL_INTERNAL_INSTR = 512; // instr to wait per bit if internal clock
this.enableSerial = 0;
this.serialHandler = GameboyJS.ConsoleSerial;
};
CPU.prototype.reset = function() {
this.memory.reset();
this.r.sp = 0xFFFE;
};
CPU.prototype.loadRom = function(data) {
this.memory.setRomData(data);
};
CPU.prototype.getRamSize = function() {
var size = 0;
switch (this.memory.rb(0x149)) {
case 1:
size = 2048;
break;
case 2:
size = 2048 * 4;
break;
case 3:
size = 2048 * 16;
break;
}
return size;
};
CPU.prototype.getGameName = function() {
var name = '';
for (var i = 0x134; i < 0x143; i++) {
var char = this.memory.rb(i) || 32;
name += String.fromCharCode(char);
}
return name;
};
// Start the execution of the emulator
CPU.prototype.run = function() {
if (this.usingBootRom) {
this.r.pc = 0x0000;
} else {
this.r.pc = 0x0100;
}
this.frame();
};
CPU.prototype.stop = function() {
clearTimeout(this.nextFrameTimer);
};
// Fetch-and-execute loop
// Will execute instructions for the duration of a frame
//
// The screen unit will notify the vblank period which
// is considered the end of a frame
//
// The function is called on a regular basis with a timeout
CPU.prototype.frame = function() {
if (!this.isPaused) {
this.nextFrameTimer = setTimeout(this.frame.bind(this), 1000 / GameboyJS.Screen.physics.FREQUENCY);
}
try {
var vblank = false;
while (!vblank) {
var oldInstrCount = this.clock.c;
if (!this.isHalted) {
var opcode = this.fetchOpcode();
GameboyJS.opcodeMap[opcode](this);
this.r.F &= 0xF0; // tmp fix
if (this.enableSerial) {
var instr = this.clock.c - oldInstrCount;
this.clock.serial += instr;
if (this.clock.serial >= 8 * this.SERIAL_INTERNAL_INSTR) {
this.endSerialTransfer();
}
}
} else {
this.clock.c += 4;
}
var elapsed = this.clock.c - oldInstrCount;
vblank = this.gpu.update(elapsed);
this.timer.update(elapsed);
this.input.update();
this.apu.update(elapsed);
this.checkInterrupt();
}
this.clock.c = 0;
} catch (e) {
this.gameboy.handleException(e);
}
};
CPU.prototype.fetchOpcode = function() {
var opcode = this.memory.rb(this.r.pc++);
if (opcode === undefined) {console.log(opcode + ' at ' + (this.r.pc-1).toString(16));this.stop();return;}
if (!GameboyJS.opcodeMap[opcode]) {
console.error('Unknown opcode '+opcode.toString(16)+' at address '+(this.r.pc-1).toString(16)+', stopping execution...');
this.stop();
return null;
}
return opcode;
};
// read register
CPU.prototype.rr = function(register) {
return this.r[register];
};
// write register
CPU.prototype.wr = function(register, value) {
this.r[register] = value;
};
CPU.prototype.halt = function() {
this.isHalted = true;
};
CPU.prototype.unhalt = function() {
this.isHalted = false;
};
CPU.prototype.pause = function() {
this.isPaused = true;
};
CPU.prototype.unpause = function() {
if (this.isPaused) {
this.isPaused = false;
this.frame();
}
};
// Look for interrupt flags
CPU.prototype.checkInterrupt = function() {
if (!this.IME) {
return;
}
for (var i = 0; i < 5; i++) {
var IFval = this.memory.rb(0xFF0F);
if (GameboyJS.Util.readBit(IFval, i) && this.isInterruptEnable(i)) {
IFval &= (0xFF - (1<<i));
this.memory.wb(0xFF0F, IFval);
this.disableInterrupts();
this.clock.c += 4; // 20 clocks to serve interrupt, with 16 for RSTn
CPU.interruptRoutines[i](this);
break;
}
}
};
// Set an interrupt flag
CPU.prototype.requestInterrupt = function(type) {
var IFval = this.memory.rb(0xFF0F);
IFval |= (1 << type)
this.memory.wb(0xFF0F, IFval) ;
this.unhalt();
};
CPU.prototype.isInterruptEnable = function(type) {
return GameboyJS.Util.readBit(this.memory.rb(0xFFFF), type) != 0;
};
CPU.prototype.enableInterrupts = function() {
this.IME = true;
};
CPU.prototype.disableInterrupts = function() {
this.IME = false;
};
CPU.prototype.enableSerialTransfer = function() {
this.enableSerial = 1;
this.clock.serial = 0;
};
CPU.prototype.endSerialTransfer = function() {
this.enableSerial = 0;
var data = this.memory.rb(0xFF01);
this.memory.wb(0xFF02, 0);
this.serialHandler.out(data);
this.memory.wb(0xFF01, this.serialHandler.in());
};
CPU.prototype.resetDivTimer = function() {
this.timer.resetDiv();
};
GameboyJS.CPU = CPU;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,73 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
var Debug = {};
// Output a range of 16 memory addresses
Debug.view_memory = function(addr, gameboy) {
var memory = gameboy.cpu.memory;
addr = addr & 0xFFF0;
var pad = '00';
var str = addr.toString(16) + ':';
for (var i = addr; i < addr + 0x10; i++) {
if ((i & 0x1) == 0) {
str += ' ';
}
var val = memory[i] || 0;
val = val.toString(16);
str += pad.substring(val.length) + val;
}
return str;
};
Debug.view_tile = function(gameboy, index, dataStart) {
var memory = gameboy.cpu.memory;
var screen = gameboy.screen;
var LCDC = screen.deviceram(screen.LCDC);
if (typeof dataStart === 'undefined') {
dataStart = 0x8000;
if (!GameboyJS.Util.readBit(LCDC, 4)) {
dataStart = 0x8800;
index = GameboyJS.cpuOps._getSignedValue(index) + 128;
}
}
var tileData = screen.readTileData(index, dataStart);
var pixelData = new Array(8 * 8)
for (var line = 0; line < 8; line++) {
var b1 = tileData.shift();
var b2 = tileData.shift();
for (var pixel = 0; pixel < 8; pixel++) {
var mask = (1 << (7-pixel));
var colorValue = ((b1 & mask) >> (7-pixel)) + ((b2 & mask) >> (7-pixel))*2;
pixelData[line * 8 + pixel] = colorValue;
}
}
var i = 0;
while (pixelData.length) {
console.log(i++ + ' ' + pixelData.splice(0, 8).join(''));
}
};
Debug.list_visible_sprites = function(gameboy) {
var memory = gameboy.cpu.memory;
var indexes = new Array();
for (var i = 0xFE00; i < 0xFE9F; i += 4) {
var x = memory.oamram(i + 1);
var y = memory.oamram(i);
var tileIndex = memory.oamram(i + 2);
if (x == 0 || x >= 168) {
continue;
}
indexes.push({oamIndex:i, x:x, y:y, tileIndex:tileIndex});
}
return indexes;
};
GameboyJS.Debug = Debug;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,388 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
var Screen;
var GPU = function(screen, cpu) {
this.cpu = cpu;
this.screen = screen;
this.LCDC= 0xFF40;
this.STAT= 0xFF41;
this.SCY = 0xFF42;
this.SCX = 0xFF43;
this.LY = 0xFF44;
this.LYC = 0xFF45;
this.BGP = 0xFF47;
this.OBP0= 0xFF48;
this.OBP1= 0xFF49;
this.WY = 0xFF4A;
this.WX = 0xFF4B;
this.vram = cpu.memory.vram.bind(cpu.memory);
this.OAM_START = 0xFE00;
this.OAM_END = 0xFE9F;
this.deviceram = cpu.memory.deviceram.bind(cpu.memory);
this.oamram = cpu.memory.oamram.bind(cpu.memory);
this.VBLANK_TIME = 70224;
this.clock = 0;
this.mode = 2;
this.line = 0;
Screen = GameboyJS.Screen;
this.buffer = new Array(Screen.physics.WIDTH * Screen.physics.HEIGHT);
this.tileBuffer = new Array(8);
this.bgTileCache = {};
};
GPU.tilemap = {
HEIGHT: 32,
WIDTH: 32,
START_0: 0x9800,
START_1: 0x9C00,
LENGTH: 0x0400 // 1024 bytes = 32*32
};
GPU.prototype.update = function(clockElapsed) {
this.clock += clockElapsed;
var vblank = false;
switch (this.mode) {
case 0: // HBLANK
if (this.clock >= 204) {
this.clock -= 204;
this.line++;
this.updateLY();
if (this.line == 144) {
this.setMode(1);
vblank = true;
this.cpu.requestInterrupt(GameboyJS.CPU.INTERRUPTS.VBLANK);
this.drawFrame();
} else {
this.setMode(2);
}
}
break;
case 1: // VBLANK
if (this.clock >= 456) {
this.clock -= 456;
this.line++;
if (this.line > 153) {
this.line = 0;
this.setMode(2);
}
this.updateLY();
}
break;
case 2: // SCANLINE OAM
if (this.clock >= 80) {
this.clock -= 80;
this.setMode(3);
}
break;
case 3: // SCANLINE VRAM
if (this.clock >= 172) {
this.clock -= 172;
this.drawScanLine(this.line);
this.setMode(0);
}
break;
}
return vblank;
};
GPU.prototype.updateLY = function() {
this.deviceram(this.LY, this.line);
var STAT = this.deviceram(this.STAT);
if (this.deviceram(this.LY) == this.deviceram(this.LYC)) {
this.deviceram(this.STAT, STAT | (1 << 2));
if (STAT & (1 << 6)) {
this.cpu.requestInterrupt(GameboyJS.CPU.INTERRUPTS.LCDC);
}
} else {
this.deviceram(this.STAT, STAT & (0xFF - (1 << 2)));
}
};
GPU.prototype.setMode = function(mode) {
this.mode = mode;
var newSTAT = this.deviceram(this.STAT);
newSTAT &= 0xFC;
newSTAT |= mode;
this.deviceram(this.STAT, newSTAT);
if (mode < 3) {
if (newSTAT & (1 << (3+mode))) {
this.cpu.requestInterrupt(GameboyJS.CPU.INTERRUPTS.LCDC);
}
}
};
// Push one scanline into the main buffer
GPU.prototype.drawScanLine = function(line) {
var LCDC = this.deviceram(this.LCDC);
var enable = GameboyJS.Util.readBit(LCDC, 7);
if (enable) {
var lineBuffer = new Array(Screen.physics.WIDTH);
this.drawBackground(LCDC, line, lineBuffer);
this.drawSprites(LCDC, line, lineBuffer);
// TODO draw a line for the window here too
}
};
GPU.prototype.drawFrame = function() {
var LCDC = this.deviceram(this.LCDC);
var enable = GameboyJS.Util.readBit(LCDC, 7);
if (enable) {
//this.drawSprites(LCDC);
this.drawWindow(LCDC);
}
this.bgTileCache = {};
this.screen.render(this.buffer);
};
GPU.prototype.drawBackground = function(LCDC, line, lineBuffer) {
if (!GameboyJS.Util.readBit(LCDC, 0)) {
return;
}
var mapStart = GameboyJS.Util.readBit(LCDC, 3) ? GPU.tilemap.START_1 : GPU.tilemap.START_0;
var dataStart, signedIndex = false;
if (GameboyJS.Util.readBit(LCDC, 4)) {
dataStart = 0x8000;
} else {
dataStart = 0x8800;
signedIndex = true;
}
var bgx = this.deviceram(this.SCX);
var bgy = this.deviceram(this.SCY);
var tileLine = ((line + bgy) & 7);
// browse BG tilemap for the line to render
var tileRow = ((((bgy + line) / 8) | 0) & 0x1F);
var firstTile = ((bgx / 8) | 0) + 32 * tileRow;
var lastTile = firstTile + Screen.physics.WIDTH / 8 + 1;
if ((lastTile & 0x1F) < (firstTile & 0x1F)) {
lastTile -= 32;
}
var x = (firstTile & 0x1F) * 8 - bgx; // x position of the first tile's leftmost pixel
for (var i = firstTile; i != lastTile; i++, (i & 0x1F) == 0 ? i-=32 : null) {
var tileIndex = this.vram(i + mapStart);
if (signedIndex) {
tileIndex = GameboyJS.Util.getSignedValue(tileIndex) + 128;
}
// try to retrieve the tile data from the cache, or use readTileData() to read from ram
// TODO find a better cache system now that the BG is rendered line by line
var tileData = this.bgTileCache[tileIndex] || (this.bgTileCache[tileIndex] = this.readTileData(tileIndex, dataStart));
this.drawTileLine(tileData, tileLine);
this.copyBGTileLine(lineBuffer, this.tileBuffer, x);
x += 8;
}
this.copyLineToBuffer(lineBuffer, line);
};
// Copy a tile line from a tileBuffer to a line buffer, at a given x position
GPU.prototype.copyBGTileLine = function(lineBuffer, tileBuffer, x) {
// copy tile line to buffer
for (var k = 0; k < 8; k++, x++) {
if (x < 0 || x >= Screen.physics.WIDTH) continue;
lineBuffer[x] = tileBuffer[k];
}
};
// Copy a scanline into the main buffer
GPU.prototype.copyLineToBuffer = function(lineBuffer, line) {
var bgPalette = GPU.getPalette(this.deviceram(this.BGP));
for (var x = 0; x < Screen.physics.WIDTH; x++) {
var color = lineBuffer[x];
this.drawPixel(x, line, bgPalette[color]);
}
};
// Write a line of a tile (8 pixels) into a buffer array
GPU.prototype.drawTileLine = function(tileData, line, xflip, yflip) {
xflip = xflip | 0;
yflip = yflip | 0;
var l = yflip ? 7 - line : line;
var byteIndex = l * 2;
var b1 = tileData[byteIndex++];
var b2 = tileData[byteIndex++];
var offset = 8;
for (var pixel = 0; pixel < 8; pixel++) {
offset--;
var mask = (1 << offset);
var colorValue = ((b1 & mask) >> offset) + ((b2 & mask) >> offset)*2;
var p = xflip ? offset : pixel;
this.tileBuffer[p] = colorValue;
}
};
GPU.prototype.drawSprites = function(LCDC, line, lineBuffer) {
if (!GameboyJS.Util.readBit(LCDC, 1)) {
return;
}
var spriteHeight = GameboyJS.Util.readBit(LCDC, 2) ? 16 : 8;
var sprites = new Array();
for (var i = this.OAM_START; i < this.OAM_END && sprites.length < 10; i += 4) {
var y = this.oamram(i);
var x = this.oamram(i+1);
var index = this.oamram(i+2);
var flags = this.oamram(i+3);
if (y - 16 > line || y - 16 < line - spriteHeight) {
continue;
}
sprites.push({x:x, y:y, index:index, flags:flags})
}
if (sprites.length == 0) return;
// cache object to store read tiles from this frame
var cacheTile = {};
var spriteLineBuffer = new Array(Screen.physics.WIDTH);
for (var i = 0; i < sprites.length; i++) {
var sprite = sprites[i];
var tileLine = line - sprite.y + 16;
var paletteNumber = GameboyJS.Util.readBit(flags, 4);
var xflip = GameboyJS.Util.readBit(sprite.flags, 5);
var yflip = GameboyJS.Util.readBit(sprite.flags, 6);
var tileData = cacheTile[sprite.index] || (cacheTile[sprite.index] = this.readTileData(sprite.index, 0x8000, spriteHeight * 2));
this.drawTileLine(tileData, tileLine, xflip, yflip);
this.copySpriteTileLine(spriteLineBuffer, this.tileBuffer, sprite.x - 8, paletteNumber);
}
this.copySpriteLineToBuffer(spriteLineBuffer, line);
};
// Copy a tile line from a tileBuffer to a line buffer, at a given x position
GPU.prototype.copySpriteTileLine = function(lineBuffer, tileBuffer, x, palette) {
// copy tile line to buffer
for (var k = 0; k < 8; k++, x++) {
if (x < 0 || x >= Screen.physics.WIDTH || tileBuffer[k] == 0) continue;
lineBuffer[x] = {color:tileBuffer[k], palette: palette};
}
};
// Copy a sprite scanline into the main buffer
GPU.prototype.copySpriteLineToBuffer = function(spriteLineBuffer, line) {
var spritePalettes = {};
spritePalettes[0] = GPU.getPalette(this.deviceram(this.OBP0));
spritePalettes[1] = GPU.getPalette(this.deviceram(this.OBP1));
for (var x = 0; x < Screen.physics.WIDTH; x++) {
if (!spriteLineBuffer[x]) continue;
var color = spriteLineBuffer[x].color;
if (color === 0) continue;
var paletteNumber = spriteLineBuffer[x].palette;
this.drawPixel(x, line, spritePalettes[paletteNumber][color]);
}
};
GPU.prototype.drawTile = function(tileData, x, y, buffer, bufferWidth, xflip, yflip, spriteMode) {
xflip = xflip | 0;
yflip = yflip | 0;
spriteMode = spriteMode | 0;
var byteIndex = 0;
for (var line = 0; line < 8; line++) {
var l = yflip ? 7 - line : line;
var b1 = tileData[byteIndex++];
var b2 = tileData[byteIndex++];
for (var pixel = 0; pixel < 8; pixel++) {
var mask = (1 << (7-pixel));
var colorValue = ((b1 & mask) >> (7-pixel)) + ((b2 & mask) >> (7-pixel))*2;
if (spriteMode && colorValue == 0) continue;
var p = xflip ? 7 - pixel : pixel;
var bufferIndex = (x + p) + (y + l) * bufferWidth;
buffer[bufferIndex] = colorValue;
}
}
};
// get an array of tile bytes data (16 entries for 8*8px)
GPU.prototype.readTileData = function(tileIndex, dataStart, tileSize) {
tileSize = tileSize || 0x10; // 16 bytes / tile by default (8*8 px)
var tileData = new Array();
var tileAddressStart = dataStart + (tileIndex * 0x10);
for (var i = tileAddressStart; i < tileAddressStart + tileSize; i++) {
tileData.push(this.vram(i));
}
return tileData;
};
GPU.prototype.drawWindow = function(LCDC) {
if (!GameboyJS.Util.readBit(LCDC, 5)) {
return;
}
var buffer = new Array(256*256);
var mapStart = GameboyJS.Util.readBit(LCDC, 6) ? GPU.tilemap.START_1 : GPU.tilemap.START_0;
var dataStart, signedIndex = false;
if (GameboyJS.Util.readBit(LCDC, 4)) {
dataStart = 0x8000;
} else {
dataStart = 0x8800;
signedIndex = true;
}
// browse Window tilemap
for (var i = 0; i < GPU.tilemap.LENGTH; i++) {
var tileIndex = this.vram(i + mapStart);
if (signedIndex) {
tileIndex = GameboyJS.Util.getSignedValue(tileIndex) + 128;
}
var tileData = this.readTileData(tileIndex, dataStart);
var x = i % GPU.tilemap.WIDTH;
var y = (i / GPU.tilemap.WIDTH) | 0;
this.drawTile(tileData, x * 8, y * 8, buffer, 256);
}
var wx = this.deviceram(this.WX) - 7;
var wy = this.deviceram(this.WY);
for (var x = Math.max(0, -wx); x < Math.min(Screen.physics.WIDTH, Screen.physics.WIDTH - wx); x++) {
for (var y = Math.max(0, -wy); y < Math.min(Screen.physics.HEIGHT, Screen.physics.HEIGHT - wy); y++) {
var color = buffer[(x & 255) + (y & 255) * 256];
this.drawPixel(x + wx, y + wy, color);
}
}
};
GPU.prototype.drawPixel = function(x, y, color) {
this.buffer[y * 160 + x] = color;
};
GPU.prototype.getPixel = function(x, y) {
return this.buffer[y * 160 + x];
};
// Get the palette mapping from a given palette byte as stored in memory
// A palette will map a tile color to a final palette color index
// used with Screen.colors to get a shade of grey
GPU.getPalette = function(paletteByte) {
var palette = [];
for (var i = 0; i < 8; i += 2) {
var shade = (paletteByte & (3 << i)) >> i;
palette.push(shade);
}
return palette;
};
GameboyJS.GPU = GPU;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,70 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// Screen device
var Screen = function(canvas, pixelSize) {
this.context = canvas.getContext('2d');
this.canvas = canvas;
this.pixelSize = pixelSize || 1;
this.initImageData();
};
// Palette colors (RGB)
Screen.colors = [
[0xFF, 0xFF, 0xFF],
[0xAA, 0xAA, 0xAA],
[0x55, 0x55, 0x55],
[0x00, 0x00, 0x00]
];
Screen.physics = {
WIDTH : 160,
HEIGHT : 144,
FREQUENCY: 60
};
Screen.prototype.setPixelSize = function(pixelSize) {
this.pixelSize = pixelSize;
this.initImageData();
};
Screen.prototype.initImageData = function() {
this.canvas.width = Screen.physics.WIDTH * this.pixelSize;
this.canvas.height = Screen.physics.HEIGHT * this.pixelSize;
this.imageData = this.context.createImageData(this.canvas.width, this.canvas.height);
for (var i = 0; i < this.imageData.data.length; i++) {
this.imageData.data[i] = 255;
}
};
Screen.prototype.clearScreen = function() {
this.context.fillStyle = '#FFF';
this.context.fillRect(0, 0, Screen.physics.WIDTH * this.pixelSize, Screen.physics.HEIGHT * this.pixelSize);
};
Screen.prototype.fillImageData = function(buffer) {
for (var y = 0; y < Screen.physics.HEIGHT; y++) {
for (var py = 0; py < this.pixelSize; py++) {
var yOffset = (y * this.pixelSize + py) * this.canvas.width;
for (var x = 0; x < Screen.physics.WIDTH; x++) {
for (var px = 0; px < this.pixelSize; px++) {
var offset = yOffset + (x * this.pixelSize + px);
var v = Screen.colors[buffer[y * Screen.physics.WIDTH + x] | 0];
// set RGB values
this.imageData.data[offset * 4] = v[0];
this.imageData.data[offset * 4 + 1] = v[1];
this.imageData.data[offset * 4 + 2] = v[2];
}
}
}
}
};
Screen.prototype.render = function(buffer) {
this.fillImageData(buffer);
this.context.putImageData(this.imageData, 0, 0);
};
GameboyJS.Screen = Screen;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,16 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// This exception should be thrown whenever a critical feature that
// has not been implemented is requested
function UnimplementedException(message, fatal) {
this.message = message;
this.name = UnimplementedException;
if (fatal === undefined) {
fatal = true;
}
this.fatal = fatal;
}
GameboyJS.UnimplementedException = UnimplementedException;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,50 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// Object for mapping the cartridge RAM
var ExtRam = function() {
this.extRam = null;
this.ramSize = 0;
this.ramBank = 0;
};
ExtRam.prototype.loadRam = function(game, size) {
this.gameName = game;
this.ramSize = size;
this.ramBanksize = this.ramSize >= 0x2000 ? 8192 : 2048;
var key = this.getStorageKey();
var data = localStorage.getItem(key);
if (data == null) {
this.extRam = Array.apply(null, new Array(this.ramSize)).map(function(){return 0;});
} else {
this.extRam = JSON.parse(data);
if (this.extRam.length != size) {
console.error('Found RAM data but not matching expected size.');
}
}
};
ExtRam.prototype.setRamBank = function(bank) {
this.ramBank = bank;
};
ExtRam.prototype.manageWrite = function(offset, value) {
this.extRam[this.ramBank * 8192 + offset] = value;
};
ExtRam.prototype.manageRead = function(offset) {
return this.extRam[this.ramBank * 8192 + offset];
};
ExtRam.prototype.getStorageKey = function() {
return this.gameName + '_EXTRAM';;
};
// Actually save the RAM in the physical storage (localStorage)
ExtRam.prototype.saveRamData = function() {
localStorage.setItem(this.getStorageKey(), JSON.stringify(this.extRam));
};
GameboyJS.ExtRam = ExtRam;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,83 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// This is the default buttons mapping for the Gamepad
// It's optimized for the XBOX pad
//
// Any other mapping can be provided as a constructor argument of the Gamepad object
// An alternative mapping should be an object with keys being the indexes
// of the gamepad buttons and values the normalized gameboy button names
var xboxMapping = {
0: 'UP',
1: 'DOWN',
2: 'LEFT',
3: 'RIGHT',
4: 'START',
5: 'SELECT',
11: 'A',
12: 'B'
};
// Gamepad listener
// Communication layer between the Gamepad API and the Input class
// Any physical controller can be used but the mapping should be provided
// in order to get an optimal layout of the buttons (see above)
var Gamepad = function(mapping) {
this.gamepad = null;
this.state = {A:0,B:0,START:0,SELECT:0,LEFT:0,RIGHT:0,UP:0,DOWN:0};
this.pullInterval = null;
this.buttonMapping = mapping || xboxMapping;
};
// Initialize the keyboard listeners and set up the callbacks
// for button press / release
Gamepad.prototype.init = function(onPress, onRelease) {
this.onPress = onPress;
this.onRelease = onRelease;
var self = this;
window.addEventListener('gamepadconnected', function(e) {
self.gamepad = e.gamepad;
self.activatePull();
});
window.addEventListener('gamepaddisconnected', function(e) {
self.gamepad = null;
self.deactivatePull();
});
};
Gamepad.prototype.activatePull = function() {
this.deactivatePull();
this.pullInterval = setInterval(this.pullState.bind(this), 100);
};
Gamepad.prototype.deactivatePull = function() {
clearInterval(this.pullInterval);
};
// Check the state of the current gamepad in order to detect any press/release action
Gamepad.prototype.pullState = function() {
for (var index in this.buttonMapping) {
var button = this.buttonMapping[index];
var oldState = this.state[button];
this.state[button] = this.gamepad.buttons[index].pressed;
if (this.state[button] == 1 && oldState == 0) {
this.managePress(button);
} else if (this.state[button] == 0 && oldState == 1) {
this.manageRelease(button);
}
}
};
Gamepad.prototype.managePress = function(key) {
this.onPress(key);
};
Gamepad.prototype.manageRelease = function(key) {
this.onRelease(key);
};
GameboyJS.Gamepad = Gamepad;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,57 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// The Input management system
//
// The pressKey() and releaseKey() functions should be called by a device class
// like GameboyJS.Keyboard after a physical button trigger event
//
// They rely on the name of the original buttons as parameters (see Input.keys)
var Input = function(cpu, pad) {
this.cpu = cpu;
this.memory = cpu.memory;
this.P1 = 0xFF00;
this.state = 0;
pad.init(this.pressKey.bind(this), this.releaseKey.bind(this));
};
Input.keys = {
START: 0x80,
SELECT: 0x40,
B: 0x20,
A: 0x10,
DOWN: 0x08,
UP: 0x04,
LEFT: 0x02,
RIGHT: 0x01
};
Input.prototype.pressKey = function(key) {
this.state |= Input.keys[key];
this.cpu.requestInterrupt(GameboyJS.CPU.INTERRUPTS.HILO);
};
Input.prototype.releaseKey = function(key) {
var mask = 0xFF - Input.keys[key];
this.state &= mask;
};
Input.prototype.update = function() {
var value = this.memory.rb(this.P1);
value = ((~value) & 0x30); // invert the value so 1 means 'active'
if (value & 0x10) { // direction keys listened
value |= (this.state & 0x0F);
} else if (value & 0x20) { // action keys listened
value |= ((this.state & 0xF0) >> 4);
} else if ((value & 0x30) == 0) { // no keys listened
value &= 0xF0;
}
value = ((~value) & 0x3F); // invert back
this.memory[this.P1] = value;
};
GameboyJS.Input = Input;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,71 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// Keyboard listener
// Does the mapping between the keyboard and the Input class
var Keyboard = function() {};
// Initialize the keyboard listeners and set up the callbacks
// for button press / release
Keyboard.prototype.init = function(onPress, onRelease) {
this.onPress = onPress;
this.onRelease = onRelease;
var self = this;
document.addEventListener('keydown', function(e) {
self.managePress(e.keyCode);
});
document.addEventListener('keyup', function(e) {
self.manageRelease(e.keyCode);
});
}
Keyboard.prototype.managePress = function(keycode) {
var key = this.translateKey(keycode);
if (key) {
this.onPress(key);
}
};
Keyboard.prototype.manageRelease = function(keycode) {
var key = this.translateKey(keycode);
if (key) {
this.onRelease(key);
}
};
// Transform a keyboard keycode into a key of the Input.keys object
Keyboard.prototype.translateKey = function(keycode) {
var key = null;
switch (keycode) {
case 71: // G
key = 'A';
break;
case 66: // B
key = 'B';
break;
case 72: // H
key = 'START';
break;
case 78: // N
key = 'SELECT';
break;
case 37: // left
key = 'LEFT';
break;
case 38: // up
key = 'UP';
break;
case 39: // right
key = 'RIGHT';
break;
case 40: // down
key = 'DOWN';
break;
}
return key;
};
GameboyJS.Keyboard = Keyboard;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,186 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// List of CPU operations
// Most operations have been factorized here to limit code redundancy
//
// How to read operations:
// Uppercase letters qualify the kind of operation (LD = LOAD, INC = INCREMENT, etc.)
// Lowercase letters are used to hint parameters :
// r = register, n = 1 memory byte, sp = sp register,
// a = suffix for memory address, i = bit index
// Example : LDrrar = LOAD operation with two-registers memory address
// as first parameter and one register value as second
//
// Underscore-prefixed functions are here to delegate the logic between similar operations,
// they should not be called from outside
//
// It's up to each operation to update the CPU clock
var ops = {
LDrrnn: function(p, r1, r2) {p.wr(r2, p.memory.rb(p.r.pc));p.wr(r1, p.memory.rb(p.r.pc+1)); p.r.pc+=2;p.clock.c += 12;},
LDrrar: function(p, r1, r2, r3) {ops._LDav(p, GameboyJS.Util.getRegAddr(p, r1, r2), p.r[r3]);p.clock.c += 8;},
LDrrra: function(p, r1, r2, r3) {p.wr(r1, p.memory.rb(GameboyJS.Util.getRegAddr(p, r2, r3)));p.clock.c += 8;},
LDrn: function(p, r1) {p.wr(r1, p.memory.rb(p.r.pc++));p.clock.c += 8;},
LDrr: function(p, r1, r2) {p.wr(r1, p.r[r2]);p.clock.c += 4;},
LDrar: function(p, r1, r2) {p.memory.wb(p.r[r1]+0xFF00, p.r[r2]);p.clock.c += 8;},
LDrra: function(p, r1, r2) {p.wr(r1, p.memory.rb(p.r[r2]+0xFF00));p.clock.c += 8;},
LDspnn: function(p) {p.wr('sp', (p.memory.rb(p.r.pc + 1) << 8) + p.memory.rb(p.r.pc));p.r.pc+=2;p.clock.c += 12;},
LDsprr: function(p, r1, r2) {p.wr('sp', GameboyJS.Util.getRegAddr(p, r1, r2));p.clock.c += 8;},
LDnnar: function(p, r1) {var addr=(p.memory.rb(p.r.pc + 1) << 8) + p.memory.rb(p.r.pc);p.memory.wb(addr,p.r[r1]);p.r.pc+=2; p.clock.c += 16;},
LDrnna: function(p, r1) {var addr=(p.memory.rb(p.r.pc + 1) << 8) + p.memory.rb(p.r.pc);p.wr(r1, p.memory.rb(addr));p.r.pc+=2; p.clock.c += 16;},
LDrrspn:function(p, r1, r2) {var rel = p.memory.rb(p.r.pc++);rel=GameboyJS.Util.getSignedValue(rel);var val=p.r.sp + rel;
var c = (p.r.sp&0xFF) + (rel&0xFF) > 0xFF;var h = (p.r.sp & 0xF) + (rel & 0xF) > 0xF;val &= 0xFFFF;
var f = 0; if(h)f|=0x20;if(c)f|=0x10;p.wr('F', f);
p.wr(r1, val >> 8);p.wr(r2, val&0xFF);
p.clock.c+=12;},
LDnnsp: function(p) {var addr = p.memory.rb(p.r.pc++) + (p.memory.rb(p.r.pc++)<<8); ops._LDav(p, addr, p.r.sp & 0xFF);ops._LDav(p, addr+1, p.r.sp >> 8);p.clock.c+=20;},
LDrran: function(p, r1, r2){var addr = GameboyJS.Util.getRegAddr(p, r1, r2);ops._LDav(p, addr, p.memory.rb(p.r.pc++));p.clock.c+=12;},
_LDav: function(p, addr, val){p.memory.wb(addr, val);},
LDHnar: function(p, r1){p.memory.wb(0xFF00 + p.memory.rb(p.r.pc++), p.r[r1]);p.clock.c+=12;},
LDHrna: function(p, r1){p.wr(r1, p.memory.rb(0xFF00 + p.memory.rb(p.r.pc++)));p.clock.c+=12;},
INCrr: function(p, r1, r2) {p.wr(r2, (p.r[r2]+1)&0xFF); if (p.r[r2] == 0) p.wr(r1, (p.r[r1]+1)&0xFF);p.clock.c += 8;},
INCrra: function(p, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);var val = (p.memory.rb(addr)+1)&0xFF;var z = val==0;var h=(p.memory.rb(addr)&0xF)+1 > 0xF;
p.memory.wb(addr, val);
p.r.F&=0x10;if(h)p.r.F|=0x20;if(z)p.r.F|=0x80;
p.clock.c+=12;},
INCsp: function(p){p.wr('sp', p.r.sp+1); p.r.sp &= 0xFFFF; p.clock.c+=8;},
INCr: function(p, r1) {var h = ((p.r[r1]&0xF) + 1)&0x10;p.wr(r1, (p.r[r1] + 1)&0xFF);var z = p.r[r1]==0;
p.r.F&=0x10;if(h)p.r.F|=0x20;if(z)p.r.F|=0x80;
p.clock.c += 4;},
DECrr: function(p, r1, r2) {p.wr(r2, (p.r[r2] - 1) & 0xFF); if (p.r[r2] == 0xFF) p.wr(r1, (p.r[r1] - 1)&0xFF);p.clock.c += 8;},
DECsp: function(p){p.wr('sp', p.r.sp-1); p.r.sp &= 0xFFFF; p.clock.c+=8;},
DECr: function(p, r1) {var h = (p.r[r1]&0xF) < 1;p.wr(r1, (p.r[r1] - 1) & 0xFF);var z = p.r[r1]==0;
p.r.F&=0x10;p.r.F|=0x40;if(h)p.r.F|=0x20;if(z)p.r.F|=0x80;
p.clock.c += 4;},
DECrra: function(p, r1, r2){var addr = GameboyJS.Util.getRegAddr(p, r1, r2);var val = (p.memory.rb(addr)-1)&0xFF;var z = val==0;var h=(p.memory.rb(addr)&0xF) < 1;
p.memory.wb(addr, val);
p.r.F&=0x10;p.r.F|=0x40;if(h)p.r.F|=0x20;if(z)p.r.F|=0x80;
p.clock.c+=12;},
ADDrr: function(p, r1, r2) {var n = p.r[r2];ops._ADDrn(p, r1, n); p.clock.c += 4;},
ADDrn: function(p, r1) {var n = p.memory.rb(p.r.pc++);ops._ADDrn(p, r1, n); p.clock.c+=8;},
_ADDrn: function(p, r1, n) {var h=((p.r[r1]&0xF)+(n&0xF))&0x10;p.wr(r1, p.r[r1]+n);var c=p.r[r1]&0x100;p.r[r1]&=0xFF;
var f = 0;if (p.r[r1]==0)f|=0x80;if (h)f|=0x20;if (c)f|=0x10;p.wr('F', f);},
ADDrrrr:function(p, r1, r2, r3, r4) {ops._ADDrrn(p, r1, r2, (p.r[r3]<<8) + p.r[r4]); p.clock.c+=8;},
ADDrrsp:function(p, r1, r2) {ops._ADDrrn(p, r1, r2, p.r.sp); p.clock.c += 8;},
ADDspn: function(p) {var v = p.memory.rb(p.r.pc++);v = GameboyJS.Util.getSignedValue(v);
var c = ((p.r.sp&0xFF) + (v&0xFF)) > 0xFF; var h = (p.r.sp & 0xF) + (v&0xF) > 0xF;
var f = 0; if(h)f|=0x20;if(c)f|=0x10;p.wr('F', f);
p.wr('sp', (p.r.sp + v) & 0xFFFF);
p.clock.c+=16;},
_ADDrrn:function(p, r1, r2, n) {var v1 = (p.r[r1]<<8) + p.r[r2];var v2 = n;
var res = v1 + v2;var c = res&0x10000;var h = ((v1&0xFFF) + (v2&0xFFF))&0x1000;var z = p.r.F&0x80;
res&=0xFFFF;p.r[r2]=res&0xFF;res=res>>8;p.r[r1]=res&0xFF;
var f=0;if(z)f|=0x80;if(h)f|=0x20;if(c)f|=0x10;p.r.F=f;},
ADCrr: function(p, r1, r2) {var n = p.r[r2]; ops._ADCrn(p, r1, n); p.clock.c += 4;},
ADCrn: function(p, r1) {var n = p.memory.rb(p.r.pc++); ops._ADCrn(p, r1, n); p.clock.c += 8;},
_ADCrn: function(p, r1, n) {
var c = p.r.F&0x10?1:0;var h=((p.r[r1]&0xF)+(n&0xF)+c)&0x10;
p.wr(r1, p.r[r1]+n+c);c=p.r[r1]&0x100;p.r[r1]&=0xFF;
var f = 0;if (p.r[r1]==0)f|=0x80;if (h)f|=0x20;if (c)f|=0x10;p.r.F=f;},
ADCrrra:function(p, r1, r2, r3) {var n = p.memory.rb(GameboyJS.Util.getRegAddr(p, r2, r3)); ops._ADCrn(p, r1, n); p.clock.c += 8;},
ADDrrra:function(p, r1, r2, r3) {var v = p.memory.rb(GameboyJS.Util.getRegAddr(p, r2, r3));var h=((p.r[r1]&0xF)+(v&0xF))&0x10;p.wr(r1, p.r[r1]+v);var c=p.r[r1]&0x100;p.r[r1]&=0xFF;
var f = 0;if (p.r[r1]==0)f|=0x80;if (h)f|=0x20;if (c)f|=0x10;p.wr('F', f);
p.clock.c += 8;},
SUBr: function(p, r1) {var n = p.r[r1];ops._SUBn(p, n);p.clock.c += 4;},
SUBn: function(p) {var n = p.memory.rb(p.r.pc++);ops._SUBn(p, n);p.clock.c += 8;},
SUBrra: function(p, r1, r2) {var n = p.memory.rb(GameboyJS.Util.getRegAddr(p, r1, r2));ops._SUBn(p, n);p.clock.c+=8;},
_SUBn: function(p, n) {var c = p.r.A < n;var h = (p.r.A&0xF) < (n&0xF);
p.wr('A', p.r.A - n);p.r.A&=0xFF; var z = p.r.A==0;
var f = 0x40;if (z)f|=0x80;if (h)f|=0x20;if (c)f|=0x10;p.wr('F', f);},
SBCn: function(p) {var n = p.memory.rb(p.r.pc++); ops._SBCn(p, n); p.clock.c += 8;},
SBCr: function(p, r1) {var n = p.r[r1]; ops._SBCn(p, n); p.clock.c += 4;},
SBCrra: function(p, r1, r2) {var v = p.memory.rb((p.r[r1] << 8) + p.r[r2]); ops._SBCn(p, v); p.clock.c += 8;},
_SBCn: function(p, n) {var carry = p.r.F&0x10 ? 1 : 0;
var c = p.r.A < n + carry;var h = (p.r.A&0xF) < (n&0xF) + carry;
p.wr('A', p.r.A - n - carry); p.r.A&=0xFF; var z = p.r.A == 0;
var f = 0x40;if (z)f|=0x80;if (h)f|=0x20;if (c)f|=0x10;p.r.F=f;},
ORr: function(p, r1) {p.r.A|=p.r[r1];p.r.F=(p.r.A==0)?0x80:0x00;p.clock.c += 4;},
ORn: function(p) {p.r.A|=p.memory.rb(p.r.pc++);p.r.F=(p.r.A==0)?0x80:0x00;p.clock.c += 8;},
ORrra: function(p, r1, r2) {p.r.A|=p.memory.rb((p.r[r1] << 8)+ p.r[r2]);p.r.F=(p.r.A==0)?0x80:0x00;p.clock.c += 8;},
ANDr: function(p, r1) {p.r.A&=p.r[r1];p.r.F=(p.r.A==0)?0xA0:0x20;p.clock.c += 4;},
ANDn: function(p) {p.r.A&=p.memory.rb(p.r.pc++);p.r.F=(p.r.A==0)?0xA0:0x20;p.clock.c += 8;},
ANDrra: function(p, r1, r2) {p.r.A&=p.memory.rb(GameboyJS.Util.getRegAddr(p, r1, r2));p.r.F=(p.r.A==0)?0xA0:0x20;p.clock.c += 8;},
XORr: function(p, r1) {p.r.A^=p.r[r1];p.r.F=(p.r.A==0)?0x80:0x00;p.clock.c += 4;},
XORn: function(p) {p.r.A^=p.memory.rb(p.r.pc++);p.r.F=(p.r.A==0)?0x80:0x00;p.clock.c += 8;},
XORrra: function(p, r1, r2) {p.r.A^=p.memory.rb((p.r[r1] << 8)+ p.r[r2]);p.r.F=(p.r.A==0)?0x80:0x00;p.clock.c += 8;},
CPr: function(p, r1) {var n = p.r[r1];ops._CPn(p, n); p.clock.c += 4;},
CPn: function(p) {var n =p.memory.rb(p.r.pc++);ops._CPn(p, n);p.clock.c+=8;},
CPrra: function(p, r1, r2) {var n = p.memory.rb(GameboyJS.Util.getRegAddr(p, r1, r2));ops._CPn(p, n);p.clock.c+=8;},
_CPn: function(p, n) {
var c = p.r.A < n;var z = p.r.A == n;var h = (p.r.A&0xF) < (n&0xF);
var f = 0x40;if(z)f+=0x80;if (h)f+=0x20;if (c)f+=0x10;p.r.F=f;},
RRCr: function(p, r1) {p.r.F=0;var out=p.r[r1] & 0x01;if(out)p.r.F|=0x10;p.r[r1]=(p.r[r1]>>1)|(out*0x80);if(p.r[r1]==0)p.r.F|=0x80;p.clock.c+=4;},
RRCrra: function(p, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);p.r.F=0;var out=p.memory.rb(addr)&0x01;if(out)p.r.F|=0x10;p.memory.wb(addr, (p.memory.rb(addr)>>1)|(out*0x80));if(p.memory.rb(addr)==0)p.r.F|=0x80;p.clock.c+=12;},
RLCr: function(p, r1) {p.r.F=0;var out=p.r[r1]&0x80?1:0;if(out)p.r.F|=0x10;p.r[r1]=((p.r[r1]<<1)+out)&0xFF;if(p.r[r1]==0)p.r.F|=0x80;p.clock.c+=4;},
RLCrra: function(p, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);p.r.F=0;var out=p.memory.rb(addr)&0x80?1:0;if(out)p.r.F|=0x10;p.memory.wb(addr, ((p.memory.rb(addr)<<1)+out)&0xFF);if(p.memory.rb(addr)==0)p.r.F|=0x80;p.clock.c+=12;},
RLr: function(p, r1) {var c=(p.r.F&0x10)?1:0;p.r.F=0;var out=p.r[r1]&0x80;out?p.r.F|=0x10:p.r.F&=0xEF;p.r[r1]=((p.r[r1]<<1)+c)&0xFF;if(p.r[r1]==0)p.r.F|=0x80;p.clock.c+=4;},
RLrra: function(p, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);var c=(p.r.F&0x10)?1:0;p.r.F=0;var out=p.memory.rb(addr)&0x80;out?p.r.F|=0x10:p.r.F&=0xEF;p.memory.wb(addr,((p.memory.rb(addr)<<1)+c)&0xFF);if(p.memory.rb(addr)==0)p.r.F|=0x80;p.clock.c+=12;},
RRr: function(p, r1) {var c=(p.r.F&0x10)?1:0;p.r.F=0;var out=p.r[r1]&0x01;out?p.r.F|=0x10:p.r.F&=0xEF;p.r[r1]=(p.r[r1]>>1)|(c*0x80);if(p.r[r1]==0)p.r.F|=0x80;p.clock.c+=4;},
RRrra: function(p, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);var c=(p.r.F&0x10)?1:0;p.r.F=0;var out=p.memory.rb(addr)&0x01;out?p.r.F|=0x10:p.r.F&=0xEF;p.memory.wb(addr,(p.memory.rb(addr)>>1)|(c*0x80));if(p.memory.rb(addr)==0)p.r.F|=0x80;p.clock.c+=12;},
SRAr: function(p, r1) {p.r.F = 0;if (p.r[r1]&0x01)p.r.F|=0x10;var msb=p.r[r1]&0x80;p.r[r1]=(p.r[r1]>>1)|msb;if (p.r[r1]==0)p.r.F|=0x80;p.clock.c+=4;},
SRArra: function(p, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);p.r.F = 0;if (p.memory.rb(addr)&0x01)p.r.F|=0x10;var msb=p.memory.rb(addr)&0x80;p.memory.wb(addr, (p.memory.rb(addr)>>1)|msb);if (p.memory.rb(addr)==0)p.r.F|=0x80;p.clock.c+=12;},
SLAr: function(p, r1) {p.r.F = 0;if (p.r[r1]&0x80)p.r.F|=0x10;p.r[r1]=(p.r[r1]<<1)&0xFF;if (p.r[r1]==0)p.r.F|=0x80;p.clock.c+=4;},
SLArra: function(p, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);p.r.F = 0;if (p.memory.rb(addr)&0x80)p.r.F|=0x10;p.memory.wb(addr, (p.memory.rb(addr)<<1)&0xFF);if (p.memory.rb(addr)==0)p.r.F|=0x80;p.clock.c+=12;},
SRLr: function(p, r1) {p.r.F = 0;if (p.r[r1]&0x01)p.r.F|=0x10;p.r[r1]=p.r[r1]>>1;if (p.r[r1]==0)p.r.F|=0x80;p.clock.c+=4;},
SRLrra: function(p, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);p.r.F = 0;if (p.memory.rb(addr)&0x01)p.r.F|=0x10;p.memory.wb(addr, p.memory.rb(addr)>>1);if (p.memory.rb(addr)==0)p.r.F|=0x80;p.clock.c+=12;},
BITir: function(p, i, r1) {var mask=1<<i;var z=(p.r[r1]&mask)?0:1;var f=p.r.F&0x10;f |= 0x20;if(z)f|=0x80;p.r.F=f;p.clock.c+=4;},
BITirra:function(p, i, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);var mask=1<<i;var z=(p.memory.rb(addr)&mask)?0:1;var f=p.r.F&0x10;f |= 0x20;if(z)f|=0x80;p.r.F=f;p.clock.c+=8;},
SETir: function(p, i, r1) {var mask=1<<i;p.r[r1]|=mask;p.clock.c += 4;},
SETirra:function(p, i, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);var mask=1<<i;p.memory.wb(addr, p.memory.rb(addr)|mask);p.clock.c += 12;},
RESir: function(p, i, r1) {var mask=0xFF - (1<<i);p.r[r1]&=mask;p.clock.c += 4;},
RESirra:function(p, i, r1, r2) {var addr = GameboyJS.Util.getRegAddr(p, r1, r2);var mask=0xFF - (1<<i);p.memory.wb(addr, p.memory.rb(addr)&mask);p.clock.c += 12;},
SWAPr: function(p, r1) {p.r[r1] = ops._SWAPn(p, p.r[r1]);p.clock.c+=4;},
SWAPrra:function(p, r1, r2){var addr = (p.r[r1] << 8)+ p.r[r2]; p.memory.wb(addr, ops._SWAPn(p, p.memory.rb(addr))); p.clock.c+=12;},
_SWAPn: function(p, n){p.r.F = n==0?0x80:0;return ((n&0xF0) >> 4) | ((n&0x0F) << 4);},
JPnn: function(p) {p.wr('pc', (p.memory.rb(p.r.pc+1) << 8) + p.memory.rb(p.r.pc));p.clock.c += 16;},
JRccn: function(p, cc) {if (GameboyJS.Util.testFlag(p, cc)){var v=p.memory.rb(p.r.pc++);v=GameboyJS.Util.getSignedValue(v);p.r.pc += v;p.clock.c+=4;}else{p.r.pc++;}p.clock.c += 8;},
JPccnn: function(p, cc) {if (GameboyJS.Util.testFlag(p, cc)){p.wr('pc', (p.memory.rb(p.r.pc+1) << 8) + p.memory.rb(p.r.pc));p.clock.c+=4;}else{p.r.pc+=2;}p.clock.c += 12;},
JPrr: function(p, r1, r2) {p.r.pc = (p.r[r1] << 8) + p.r[r2];p.clock.c += 4;},
JRn: function(p) {var v=p.memory.rb(p.r.pc++);v=GameboyJS.Util.getSignedValue(v);p.r.pc += v;p.clock.c += 12;},
PUSHrr: function(p, r1, r2) {p.wr('sp', p.r.sp-1);p.memory.wb(p.r.sp, p.r[r1]);p.wr('sp', p.r.sp-1);p.memory.wb(p.r.sp, p.r[r2]);p.clock.c+=16;},
POPrr: function(p, r1, r2) {p.wr(r2, p.memory.rb(p.r.sp));p.wr('sp', p.r.sp+1);p.wr(r1, p.memory.rb(p.r.sp));p.wr('sp', p.r.sp+1);p.clock.c+=12;},
RSTn: function(p, n) {p.wr('sp', p.r.sp-1);p.memory.wb(p.r.sp,p.r.pc>>8);p.wr('sp', p.r.sp-1);p.memory.wb(p.r.sp,p.r.pc&0xFF);p.r.pc=n;p.clock.c+=16;},
RET: function(p) {p.r.pc = p.memory.rb(p.r.sp);p.wr('sp', p.r.sp+1);p.r.pc+=p.memory.rb(p.r.sp)<<8;p.wr('sp', p.r.sp+1);p.clock.c += 16;},
RETcc: function(p, cc) {if (GameboyJS.Util.testFlag(p, cc)){p.r.pc = p.memory.rb(p.r.sp);p.wr('sp', p.r.sp+1);p.r.pc+=p.memory.rb(p.r.sp)<<8;p.wr('sp', p.r.sp+1);p.clock.c+=12;}p.clock.c+=8;},
CALLnn: function(p) {ops._CALLnn(p); p.clock.c+=24;},
CALLccnn:function(p, cc) {if (GameboyJS.Util.testFlag(p, cc)){ops._CALLnn(p);p.clock.c+=12;}else{p.r.pc+=2;}p.clock.c+=12; },
_CALLnn:function(p){p.wr('sp', p.r.sp - 1); p.memory.wb(p.r.sp, ((p.r.pc+2)&0xFF00)>>8);
p.wr('sp', p.r.sp - 1); p.memory.wb(p.r.sp, (p.r.pc+2)&0x00FF);
var j=p.memory.rb(p.r.pc)+(p.memory.rb(p.r.pc+1)<<8);p.r.pc=j;},
CPL: function(p) {p.wr('A', (~p.r.A)&0xFF);p.r.F|=0x60,p.clock.c += 4;},
CCF: function(p) {p.r.F&=0x9F;p.r.F&0x10?p.r.F&=0xE0:p.r.F|=0x10;p.clock.c += 4;},
SCF: function(p) {p.r.F&=0x9F;p.r.F|=0x10;p.clock.c+=4;},
DAA: function(p) {
var sub = (p.r.F&0x40) ? 1 : 0; var h = (p.r.F&0x20)?1:0;var c = (p.r.F&0x10)?1:0;
if (sub) {
if (h) {
p.r.A = (p.r.A - 0x6) & 0xFF;
}
if (c) {
p.r.A -= 0x60;
}
} else {
if ((p.r.A&0xF) > 9 || h) {
p.r.A += 0x6;
}
if (p.r.A > 0x9F || c) {
p.r.A += 0x60;
}
}
if (p.r.A&0x100) c = 1;
p.r.A &= 0xFF;
p.r.F &= 0x40;if (p.r.A == 0) p.r.F|=0x80;if (c) p.r.F|=0x10;
p.clock.c += 4;
},
HALT: function(p) {p.halt(); p.clock.c+=4;},
DI: function(p) {p.disableInterrupts();p.clock.c += 4;},
EI: function(p) {p.enableInterrupts();p.clock.c += 4;},
RETI: function(p) {p.enableInterrupts();ops.RET(p);},
CB: function(p) {var opcode = p.memory.rb(p.r.pc++);
GameboyJS.opcodeCbmap[opcode](p);
p.clock.c+=4;}
};
GameboyJS.cpuOps = ops;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,123 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
var defaultOptions = {
pad: {class: GameboyJS.Keyboard, mapping: null},
zoom: 1,
romReaders: [],
statusContainerId: 'status',
gameNameContainerId: 'game-name',
errorContainerId: 'error'
};
// Gameboy class
//
// This object is the entry point of the application
// Will delegate user actions to the emulated devices
// and provide information where needed
var Gameboy = function(canvas, options) {
options = options || {};
this.options = GameboyJS.Util.extend({}, defaultOptions, options);
var cpu = new GameboyJS.CPU(this);
var screen = new GameboyJS.Screen(canvas, this.options.zoom);
var gpu = new GameboyJS.GPU(screen, cpu);
cpu.gpu = gpu;
var pad = new this.options.pad.class(this.options.pad.mapping);
var input = new GameboyJS.Input(cpu, pad);
cpu.input = input;
this.cpu = cpu;
this.screen = screen;
this.input = input;
this.pad = pad;
this.createRom(this.options.romReaders);
this.statusContainer = document.getElementById(this.options.statusContainerId) || document.createElement('div');
this.gameNameContainer = document.getElementById(this.options.gameNameContainerId) || document.createElement('div');
this.errorContainer = document.getElementById(this.options.errorContainerId) || document.createElement('div');
};
// Create the ROM object and bind one or more readers
Gameboy.prototype.createRom = function (readers) {
var rom = new GameboyJS.Rom(this);
if (readers.length == 0) {
// add the default rom reader
var romReader = new GameboyJS.RomFileReader();
rom.addReader(romReader);
} else {
for (var i in readers) {
if (readers.hasOwnProperty(i)) {
rom.addReader(readers[i]);
}
}
}
};
Gameboy.prototype.startRom = function(rom) {
this.errorContainer.classList.add('hide');
this.cpu.reset();
try {
this.cpu.loadRom(rom.data);
this.setStatus('Game Running :');
this.setGameName(this.cpu.getGameName());
this.cpu.run();
} catch (e) {
this.handleException(e);
}
};
Gameboy.prototype.pause = function(value) {
if (value) {
this.setStatus('Game Paused :');
this.cpu.pause();
} else {
this.setStatus('Game Running :');
this.cpu.unpause();
}
};
Gameboy.prototype.error = function(message) {
this.setStatus('Error during execution');
this.setError('An error occurred during execution:' + message);
this.cpu.stop();
};
Gameboy.prototype.setStatus = function(status) {
this.statusContainer.innerHTML = status;
};
// Display an error message
Gameboy.prototype.setError = function(message) {
this.errorContainer.classList.remove('hide');
this.errorContainer.innerHTML = message;
};
// Display the name of the game running
Gameboy.prototype.setGameName = function(name) {
this.gameNameContainer.innerHTML = name;
};
Gameboy.prototype.setSoundEnabled = function(value) {
if (value) {
this.cpu.apu.connect();
} else {
this.cpu.apu.disconnect();
}
};
Gameboy.prototype.setScreenZoom = function(value) {
this.screen.setPixelSize(value);
};
Gameboy.prototype.handleException = function(e) {
if (e instanceof GameboyJS.UnimplementedException) {
if (e.fatal) {
this.error('This cartridge is not supported ('+ e.message +')');
} else {
console.error(e.message);
}
} else {
throw e;
}
};
GameboyJS.Gameboy = Gameboy;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,134 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// Memory bank controllers
var MBC = {};
// Create an MBC instance depending on the type specified in the cartridge
MBC.getMbcInstance = function(memory, type) {
var instance;
switch (type) {
case 0x00:
instance = new MBC0(memory);
break;
case 0x01: case 0x02: case 0x03:
instance = new MBC1(memory);
break;
case 0x0F: case 0x10: case 0x11: case 0x12: case 0x13:
instance = new MBC3(memory);
break;
case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E:
instance = new MBC5(memory);
break;
default:
throw new GameboyJS.UnimplementedException('MBC type not supported');
}
return instance;
};
var MBC1 = function(memory) {
this.memory = memory;
this.romBankNumber = 1;
this.mode = 0; // mode 0 = ROM, mode 1 = RAM
this.ramEnabled = true;
this.extRam = new GameboyJS.ExtRam();
};
MBC1.prototype.loadRam = function(game, size) {
this.extRam.loadRam(game, size);
};
MBC1.prototype.manageWrite = function(addr, value) {
switch (addr & 0xF000) {
case 0x0000: case 0x1000: // enable RAM
this.ramEnabled = (value & 0x0A) ? true : false;
if (this.ramEnabled) {
this.extRam.saveRamData();
}
break;
case 0x2000: case 0x3000: // ROM bank number lower 5 bits
value &= 0x1F;
if (value == 0) value = 1;
var mask = this.mode ? 0 : 0xE0;
this.romBankNumber = (this.romBankNumber & mask) +value;
this.memory.loadRomBank(this.romBankNumber);
break;
case 0x4000: case 0x5000: // RAM bank or high bits ROM
value &= 0x03;
if (this.mode == 0) { // ROM upper bits
this.romBankNumber = (this.romBankNumber&0x1F) | (value << 5);
this.memory.loadRomBank(this.romBankNumber);
} else { // RAM bank
this.extRam.setRamBank(value);
}
break;
case 0x6000: case 0x7000: // ROM / RAM mode
this.mode = value & 1;
break;
case 0xA000: case 0xB000:
this.extRam.manageWrite(addr - 0xA000, value);
break;
}
};
MBC1.prototype.readRam = function(addr) {
return this.extRam.manageRead(addr - 0xA000);
};
var MBC3 = function(memory) {
this.memory = memory;
this.romBankNumber = 1;
this.ramEnabled = true;
this.extRam = new GameboyJS.ExtRam();
};
MBC3.prototype.loadRam = function(game, size) {
this.extRam.loadRam(game, size);
};
MBC3.prototype.manageWrite = function(addr, value) {
switch (addr & 0xF000) {
case 0x0000: case 0x1000: // enable RAM
this.ramEnabled = (value & 0x0A) ? true : false;
if (this.ramEnabled) {
this.extRam.saveRamData();
}
break;
case 0x2000: case 0x3000: // ROM bank number
value &= 0x7F;
if (value == 0) value = 1;
this.romBankNumber = value;
this.memory.loadRomBank(this.romBankNumber);
break;
case 0x4000: case 0x5000: // RAM bank
this.extRam.setRamBank(value);
break;
case 0x6000: case 0x7000: // Latch clock data
throw new GameboyJS.UnimplementedException('cartridge clock not supported', false);
break;
case 0xA000: case 0xB000:
this.extRam.manageWrite(addr - 0xA000, value);
break;
}
};
MBC3.prototype.readRam = function(addr) {
return this.extRam.manageRead(addr - 0xA000);
};
// declare MBC5 for compatibility with most cartriges
// does not support rumble feature
var MBC5 = MBC3;
// MBC0 exists for consistency and manages the no-MBC cartriges
var MBC0 = function(memory) {this.memory = memory;};
MBC0.prototype.manageWrite = function(addr, value) {
this.memory.loadRomBank(value);
};
MBC0.prototype.readRam = function(addr) {return 0;};
MBC0.prototype.loadRam = function() {};
GameboyJS.MBC = MBC;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,153 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// Memory unit
var Memory = function(cpu) {
this.MEM_SIZE = 65536; // 64KB
this.MBCtype = 0;
this.banksize = 0x4000;
this.rom = null;
this.mbc = null;
this.cpu = cpu;
};
Memory.addresses = {
VRAM_START : 0x8000,
VRAM_END : 0x9FFF,
EXTRAM_START : 0xA000,
EXTRAM_END : 0xBFFF,
OAM_START : 0xFE00,
OAM_END : 0xFE9F,
DEVICE_START: 0xFF00,
DEVICE_END: 0xFF7F
};
// Memory can be accessed as an Array
Memory.prototype = new Array();
Memory.prototype.reset = function() {
this.length = this.MEM_SIZE;
for (var i = Memory.addresses.VRAM_START; i <= Memory.addresses.VRAM_END; i++) {
this[i] = 0;
}
for (var i = Memory.addresses.DEVICE_START; i <= Memory.addresses.DEVICE_END; i++) {
this[i] = 0;
}
this[0xFFFF] = 0;
};
Memory.prototype.setRomData = function(data) {
this.rom = data;
this.loadRomBank(0);
this.mbc = GameboyJS.MBC.getMbcInstance(this, this[0x147]);
this.loadRomBank(1);
this.mbc.loadRam(this.cpu.getGameName(), this.cpu.getRamSize());
};
Memory.prototype.loadRomBank = function(index) {
var start = index ? 0x4000 : 0x0;
var romStart = index * 0x4000;
for (var i = 0; i < this.banksize; i++) {
this[i + start] = this.rom[romStart + i];
}
};
// Video ram accessor
Memory.prototype.vram = function(address) {
if (address < Memory.addresses.VRAM_START || address > Memory.addresses.VRAM_END) {
throw 'VRAM access in out of bounds address ' + address;
}
return this[address];
};
// OAM ram accessor
Memory.prototype.oamram = function(address) {
if (address < Memory.addresses.OAM_START || address > Memory.addresses.OAM_END) {
throw 'OAMRAM access in out of bounds address ' + address;
}
return this[address];
};
// Device ram accessor
Memory.prototype.deviceram = function(address, value) {
if (address < Memory.addresses.DEVICERAM_START || address > Memory.addresses.DEVICERAM_END) {
throw 'Device RAM access in out of bounds address ' + address;
}
if (typeof value === "undefined") {
return this[address];
} else {
this[address] = value;
}
};
// Memory read proxy function
// Used to centralize memory read access
Memory.prototype.rb = function (addr) {
if (addr >= 0xFF10 && addr < 0xFF40) {
var mask = apuMask[addr - 0xFF10];
return this[addr] | mask;
}
if ((addr >= 0xA000 && addr < 0xC000)) {
return this.mbc.readRam(addr);
}
return this[addr];
};
// Bitmasks for audio addresses reads
var apuMask = [
0x80,0x3F,0x00,0xFF,0xBF, // NR10-NR15
0xFF,0x3F,0x00,0xFF,0xBF, // NR20-NR25
0x7F,0xFF,0x9F,0xFF,0xBF, // NR30-NR35
0xFF,0xFF,0x00,0x00,0xBF, // NR40-NR45
0x00,0x00,0x70, // NR50-NR52
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // Wave RAM
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
];
// Memory write proxy function
// Used to centralize memory writes and delegate specific behaviour
// to the correct units
Memory.prototype.wb = function(addr, value) {
if (addr < 0x8000 || (addr >= 0xA000 && addr < 0xC000)) { // MBC
this.mbc.manageWrite(addr, value);
} else if (addr >= 0xFF10 && addr <= 0xFF3F) { // sound registers
this.cpu.apu.manageWrite(addr, value);
} else if (addr == 0xFF00) { // input register
this[addr] = ((this[addr] & 0x0F) | (value & 0x30));
} else {
this[addr] = value;
if ((addr & 0xFF00) == 0xFF00) {
if (addr == 0xFF02) {
if (value & 0x80) {
this.cpu.enableSerialTransfer();
}
}
if (addr == 0xFF04) {
this.cpu.resetDivTimer();
}
if (addr == 0xFF46) { // OAM DMA transfer
this.dmaTransfer(value);
}
}
}
}
// Start a DMA transfer (OAM data from cartrige to RAM)
Memory.prototype.dmaTransfer = function(startAddressPrefix) {
var startAddress = (startAddressPrefix << 8);
for (var i = 0; i < 0xA0; i++) {
this[Memory.addresses.OAM_START + i] = this[startAddress + i];
}
};
GameboyJS.Memory = Memory;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,559 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
var ops = GameboyJS.cpuOps;
// Each opcode (0 to 0xFF) is associated to a CPU operation
// CPU operations are implemented separately
// The cbmap object holds operations for CB prefixed opcodes (0xCB00 to 0xCBFF)
// Non existent opcodes are commented out and marked empty
var map = {
0x00: function(p){p.clock.c += 4;},
0x01: function(p){ops.LDrrnn(p, 'B', 'C');},
0x02: function(p){ops.LDrrar(p, 'B', 'C', 'A');},
0x03: function(p){ops.INCrr(p, 'B', 'C');},
0x04: function(p){ops.INCr(p, 'B');},
0x05: function(p){ops.DECr(p, 'B');},
0x06: function(p){ops.LDrn(p, 'B');},
0x07: function(p){var out=p.r.A & 0x80?1:0; out ? p.r.F=0x10:p.r.F=0; p.wr('A', ((p.r.A<<1)+out)&0xFF);p.clock.c+=4;},
0x08: function(p){ops.LDnnsp(p);},
0x09: function(p){ops.ADDrrrr(p, 'H', 'L', 'B', 'C');},
0x0A: function(p){ops.LDrrra(p, 'A', 'B', 'C');},
0x0B: function(p){ops.DECrr(p, 'B', 'C');},
0x0C: function(p){ops.INCr(p, 'C');},
0x0D: function(p){ops.DECr(p, 'C');},
0x0E: function(p){ops.LDrn(p, 'C');},
0x0F: function(p){var out=p.r.A & 0x01; out ? p.r.F=0x10:p.r.F=0; p.wr('A', (p.r.A>>1)|(out*0x80));p.clock.c+=4;},
0x10: function(p){p.r.pc++;p.clock.c+=4;},
0x11: function(p){ops.LDrrnn(p, 'D', 'E');},
0x12: function(p){ops.LDrrar(p, 'D', 'E', 'A');},
0x13: function(p){ops.INCrr(p, 'D', 'E');},
0x14: function(p){ops.INCr(p, 'D');},
0x15: function(p){ops.DECr(p, 'D');},
0x16: function(p){ops.LDrn(p, 'D');},
0x17: function(p){var c = (p.r.F&0x10)?1:0;var out=p.r.A & 0x80?1:0; out ? p.r.F=0x10:p.r.F=0; p.wr('A',((p.r.A<<1)+c)&0xFF);p.clock.c+=4;},
0x18: function(p){ops.JRn(p);},
0x19: function(p){ops.ADDrrrr(p, 'H', 'L', 'D', 'E');},
0x1A: function(p){ops.LDrrra(p, 'A', 'D', 'E');},
0x1B: function(p){ops.DECrr(p, 'D', 'E');},
0x1C: function(p){ops.INCr(p, 'E');},
0x1D: function(p){ops.DECr(p, 'E');},
0x1E: function(p){ops.LDrn(p, 'E');},
0x1F: function(p){var c = (p.r.F&0x10)?1:0;var out=p.r.A & 0x01; out ? p.r.F=0x10:p.r.F=0; p.wr('A', (p.r.A>>1)|(c*0x80));p.clock.c+=4;},
0x20: function(p){ops.JRccn(p, 'NZ');},
0x21: function(p){ops.LDrrnn(p, 'H', 'L');},
0x22: function(p){ops.LDrrar(p, 'H', 'L', 'A');ops.INCrr(p, 'H', 'L');p.clock.c -= 8;},
0x23: function(p){ops.INCrr(p, 'H', 'L');},
0x24: function(p){ops.INCr(p, 'H');},
0x25: function(p){ops.DECr(p, 'H');},
0x26: function(p){ops.LDrn(p, 'H');},
0x27: function(p){ops.DAA(p);},
0x28: function(p){ops.JRccn(p, 'Z');},
0x29: function(p){ops.ADDrrrr(p, 'H', 'L', 'H', 'L');},
0x2A: function(p){ops.LDrrra(p, 'A', 'H', 'L');ops.INCrr(p, 'H', 'L');p.clock.c -= 8;},
0x2B: function(p){ops.DECrr(p, 'H', 'L');},
0x2C: function(p){ops.INCr(p, 'L');},
0x2D: function(p){ops.DECr(p, 'L');},
0x2E: function(p){ops.LDrn(p, 'L');},
0x2F: function(p){ops.CPL(p);},
0x30: function(p){ops.JRccn(p, 'NC');},
0x31: function(p){ops.LDspnn(p);},
0x32: function(p){ops.LDrrar(p, 'H', 'L', 'A');ops.DECrr(p, 'H', 'L');p.clock.c -= 8;},
0x33: function(p){ops.INCsp(p);},
0x34: function(p){ops.INCrra(p, 'H', 'L');},
0x35: function(p){ops.DECrra(p, 'H', 'L');},
0x36: function(p){ops.LDrran(p, 'H', 'L');},
0x37: function(p){ops.SCF(p);},
0x38: function(p){ops.JRccn(p, 'C');},
0x39: function(p){ops.ADDrrsp(p, 'H', 'L');},
0x3A: function(p){ops.LDrrra(p, 'A', 'H', 'L');ops.DECrr(p, 'H', 'L');p.clock.c -= 8;},
0x3B: function(p){ops.DECsp(p);},
0x3C: function(p){ops.INCr(p, 'A');},
0x3D: function(p){ops.DECr(p, 'A');},
0x3E: function(p){ops.LDrn(p, 'A');},
0x3F: function(p){ops.CCF(p);},
0x40: function(p){ops.LDrr(p, 'B', 'B');},
0x41: function(p){ops.LDrr(p, 'B', 'C');},
0x42: function(p){ops.LDrr(p, 'B', 'D');},
0x43: function(p){ops.LDrr(p, 'B', 'E');},
0x44: function(p){ops.LDrr(p, 'B', 'H');},
0x45: function(p){ops.LDrr(p, 'B', 'L');},
0x46: function(p){ops.LDrrra(p, 'B', 'H', 'L');},
0x47: function(p){ops.LDrr(p, 'B', 'A');},
0x48: function(p){ops.LDrr(p, 'C', 'B');},
0x49: function(p){ops.LDrr(p, 'C', 'C');},
0x4A: function(p){ops.LDrr(p, 'C', 'D');},
0x4B: function(p){ops.LDrr(p, 'C', 'E');},
0x4C: function(p){ops.LDrr(p, 'C', 'H');},
0x4D: function(p){ops.LDrr(p, 'C', 'L');},
0x4E: function(p){ops.LDrrra(p, 'C', 'H', 'L');},
0x4F: function(p){ops.LDrr(p, 'C', 'A');},
0x50: function(p){ops.LDrr(p, 'D', 'B');},
0x51: function(p){ops.LDrr(p, 'D', 'C');},
0x52: function(p){ops.LDrr(p, 'D', 'D');},
0x53: function(p){ops.LDrr(p, 'D', 'E');},
0x54: function(p){ops.LDrr(p, 'D', 'H');},
0x55: function(p){ops.LDrr(p, 'D', 'L');},
0x56: function(p){ops.LDrrra(p, 'D', 'H', 'L');},
0x57: function(p){ops.LDrr(p, 'D', 'A');},
0x58: function(p){ops.LDrr(p, 'E', 'B');},
0x59: function(p){ops.LDrr(p, 'E', 'C');},
0x5A: function(p){ops.LDrr(p, 'E', 'D');},
0x5B: function(p){ops.LDrr(p, 'E', 'E');},
0x5C: function(p){ops.LDrr(p, 'E', 'H');},
0x5D: function(p){ops.LDrr(p, 'E', 'L');},
0x5E: function(p){ops.LDrrra(p, 'E', 'H', 'L');},
0x5F: function(p){ops.LDrr(p, 'E', 'A');},
0x60: function(p){ops.LDrr(p, 'H', 'B');},
0x61: function(p){ops.LDrr(p, 'H', 'C');},
0x62: function(p){ops.LDrr(p, 'H', 'D');},
0x63: function(p){ops.LDrr(p, 'H', 'E');},
0x64: function(p){ops.LDrr(p, 'H', 'H');},
0x65: function(p){ops.LDrr(p, 'H', 'L');},
0x66: function(p){ops.LDrrra(p, 'H', 'H', 'L');},
0x67: function(p){ops.LDrr(p, 'H', 'A');},
0x68: function(p){ops.LDrr(p, 'L', 'B');},
0x69: function(p){ops.LDrr(p, 'L', 'C');},
0x6A: function(p){ops.LDrr(p, 'L', 'D');},
0x6B: function(p){ops.LDrr(p, 'L', 'E');},
0x6C: function(p){ops.LDrr(p, 'L', 'H');},
0x6D: function(p){ops.LDrr(p, 'L', 'L');},
0x6E: function(p){ops.LDrrra(p, 'L', 'H', 'L');},
0x6F: function(p){ops.LDrr(p, 'L', 'A');},
0x70: function(p){ops.LDrrar(p, 'H', 'L', 'B');},
0x71: function(p){ops.LDrrar(p, 'H', 'L', 'C');},
0x72: function(p){ops.LDrrar(p, 'H', 'L', 'D');},
0x73: function(p){ops.LDrrar(p, 'H', 'L', 'E');},
0x74: function(p){ops.LDrrar(p, 'H', 'L', 'H');},
0x75: function(p){ops.LDrrar(p, 'H', 'L', 'L');},
0x76: function(p){ops.HALT(p);},
0x77: function(p){ops.LDrrar(p, 'H', 'L', 'A');},
0x78: function(p){ops.LDrr(p, 'A', 'B');},
0x79: function(p){ops.LDrr(p, 'A', 'C');},
0x7A: function(p){ops.LDrr(p, 'A', 'D');},
0x7B: function(p){ops.LDrr(p, 'A', 'E');},
0x7C: function(p){ops.LDrr(p, 'A', 'H');},
0x7D: function(p){ops.LDrr(p, 'A', 'L');},
0x7E: function(p){ops.LDrrra(p, 'A', 'H', 'L');},
0x7F: function(p){ops.LDrr(p, 'A', 'A');},
0x80: function(p){ops.ADDrr(p, 'A', 'B');},
0x81: function(p){ops.ADDrr(p, 'A', 'C');},
0x82: function(p){ops.ADDrr(p, 'A', 'D');},
0x83: function(p){ops.ADDrr(p, 'A', 'E');},
0x84: function(p){ops.ADDrr(p, 'A', 'H');},
0x85: function(p){ops.ADDrr(p, 'A', 'L');},
0x86: function(p){ops.ADDrrra(p, 'A', 'H', 'L');},
0x87: function(p){ops.ADDrr(p, 'A', 'A');},
0x88: function(p){ops.ADCrr(p, 'A', 'B');},
0x89: function(p){ops.ADCrr(p, 'A', 'C');},
0x8A: function(p){ops.ADCrr(p, 'A', 'D');},
0x8B: function(p){ops.ADCrr(p, 'A', 'E');},
0x8C: function(p){ops.ADCrr(p, 'A', 'H');},
0x8D: function(p){ops.ADCrr(p, 'A', 'L');},
0x8E: function(p){ops.ADCrrra(p, 'A', 'H', 'L');},
0x8F: function(p){ops.ADCrr(p, 'A', 'A');},
0x90: function(p){ops.SUBr(p, 'B');},
0x91: function(p){ops.SUBr(p, 'C');},
0x92: function(p){ops.SUBr(p, 'D');},
0x93: function(p){ops.SUBr(p, 'E');},
0x94: function(p){ops.SUBr(p, 'H');},
0x95: function(p){ops.SUBr(p, 'L');},
0x96: function(p){ops.SUBrra(p, 'H', 'L');},
0x97: function(p){ops.SUBr(p, 'A');},
0x98: function(p){ops.SBCr(p, 'B');},
0x99: function(p){ops.SBCr(p, 'C');},
0x9A: function(p){ops.SBCr(p, 'D');},
0x9B: function(p){ops.SBCr(p, 'E');},
0x9C: function(p){ops.SBCr(p, 'H');},
0x9D: function(p){ops.SBCr(p, 'L');},
0x9E: function(p){ops.SBCrra(p, 'H', 'L');},
0x9F: function(p){ops.SBCr(p, 'A');},
0xA0: function(p){ops.ANDr(p, 'B');},
0xA1: function(p){ops.ANDr(p, 'C');},
0xA2: function(p){ops.ANDr(p, 'D');},
0xA3: function(p){ops.ANDr(p, 'E');},
0xA4: function(p){ops.ANDr(p, 'H');},
0xA5: function(p){ops.ANDr(p, 'L');},
0xA6: function(p){ops.ANDrra(p, 'H', 'L');},
0xA7: function(p){ops.ANDr(p, 'A');},
0xA8: function(p){ops.XORr(p, 'B');},
0xA9: function(p){ops.XORr(p, 'C');},
0xAA: function(p){ops.XORr(p, 'D');},
0xAB: function(p){ops.XORr(p, 'E');},
0xAC: function(p){ops.XORr(p, 'H');},
0xAD: function(p){ops.XORr(p, 'L');},
0xAE: function(p){ops.XORrra(p, 'H', 'L');},
0xAF: function(p){ops.XORr(p, 'A');},
0xB0: function(p){ops.ORr(p, 'B');},
0xB1: function(p){ops.ORr(p, 'C');},
0xB2: function(p){ops.ORr(p, 'D');},
0xB3: function(p){ops.ORr(p, 'E');},
0xB4: function(p){ops.ORr(p, 'H');},
0xB5: function(p){ops.ORr(p, 'L');},
0xB6: function(p){ops.ORrra(p, 'H', 'L');},
0xB7: function(p){ops.ORr(p, 'A');},
0xB8: function(p){ops.CPr(p, 'B');},
0xB9: function(p){ops.CPr(p, 'C');},
0xBA: function(p){ops.CPr(p, 'D');},
0xBB: function(p){ops.CPr(p, 'E');},
0xBC: function(p){ops.CPr(p, 'H');},
0xBD: function(p){ops.CPr(p, 'L');},
0xBE: function(p){ops.CPrra(p, 'H', 'L');},
0xBF: function(p){ops.CPr(p, 'A');},
0xC0: function(p){ops.RETcc(p, 'NZ');},
0xC1: function(p){ops.POPrr(p, 'B', 'C');},
0xC2: function(p){ops.JPccnn(p, 'NZ');},
0xC3: function(p){ops.JPnn(p);},
0xC4: function(p){ops.CALLccnn(p, 'NZ');},
0xC5: function(p){ops.PUSHrr(p, 'B', 'C');},
0xC6: function(p){ops.ADDrn(p, 'A');},
0xC7: function(p){ops.RSTn(p, 0x00);},
0xC8: function(p){ops.RETcc(p, 'Z');},
0xC9: function(p){ops.RET(p);},
0xCA: function(p){ops.JPccnn(p, 'Z');},
0xCB: function(p){ops.CB(p);},
0xCC: function(p){ops.CALLccnn(p, 'Z');},
0xCD: function(p){ops.CALLnn(p);},
0xCE: function(p){ops.ADCrn(p, 'A');},
0xCF: function(p){ops.RSTn(p, 0x08);},
0xD0: function(p){ops.RETcc(p, 'NC');},
0xD1: function(p){ops.POPrr(p, 'D', 'E');},
0xD2: function(p){ops.JPccnn(p, 'NC');},
//0xD3 empty
0xD4: function(p){ops.CALLccnn(p, 'NC');},
0xD5: function(p){ops.PUSHrr(p, 'D', 'E');},
0xD6: function(p){ops.SUBn(p);},
0xD7: function(p){ops.RSTn(p, 0x10);},
0xD8: function(p){ops.RETcc(p, 'C');},
0xD9: function(p){ops.RETI(p);},
0xDA: function(p){ops.JPccnn(p, 'C');},
//0xDB empty
0xDC: function(p){ops.CALLccnn(p, 'C');},
//0xDD empty
0xDE: function(p){ops.SBCn(p);},
0xDF: function(p){ops.RSTn(p, 0x18);},
0xE0: function(p){ops.LDHnar(p, 'A');},
0xE1: function(p){ops.POPrr(p, 'H', 'L');},
0xE2: function(p){ops.LDrar(p, 'C', 'A');},
//0xE3 empty
//0xE4 empty
0xE5: function(p){ops.PUSHrr(p, 'H', 'L');},
0xE6: function(p){ops.ANDn(p);},
0xE7: function(p){ops.RSTn(p, 0x20);},
0xE8: function(p){ops.ADDspn(p);},
0xE9: function(p){ops.JPrr(p, 'H', 'L');},
0xEA: function(p){ops.LDnnar(p, 'A');},
//0xEB empty
//0xEC empty
//0xED empty
0xEE: function(p){ops.XORn(p);},
0xEF: function(p){ops.RSTn(p, 0x28);},
0xF0: function(p){ops.LDHrna(p, 'A');},
0xF1: function(p){ops.POPrr(p, 'A', 'F');},
0xF2: function(p){ops.LDrra(p, 'A', 'C');},
0xF3: function(p){ops.DI(p);},
//0xF4 empty
0xF5: function(p){ops.PUSHrr(p, 'A', 'F');},
0xF6: function(p){ops.ORn(p);},
0xF7: function(p){ops.RSTn(p, 0x30);},
0xF8: function(p){ops.LDrrspn(p, 'H', 'L');},
0xF9: function(p){ops.LDsprr(p, 'H', 'L');},
0xFA: function(p){ops.LDrnna(p, 'A');},
0xFB: function(p){ops.EI(p);},
//0xFC empty
//0xFD empty
0xFE: function(p){ops.CPn(p);},
0xFF: function(p){ops.RSTn(p, 0x38);}
};
var cbmap = {
0x00: function(p){ops.RLCr(p, 'B');},
0x01: function(p){ops.RLCr(p, 'C');},
0x02: function(p){ops.RLCr(p, 'D');},
0x03: function(p){ops.RLCr(p, 'E');},
0x04: function(p){ops.RLCr(p, 'H');},
0x05: function(p){ops.RLCr(p, 'L');},
0x06: function(p){ops.RLCrra(p, 'H', 'L');},
0x07: function(p){ops.RLCr(p, 'A');},
0x08: function(p){ops.RRCr(p, 'B');},
0x09: function(p){ops.RRCr(p, 'C');},
0x0A: function(p){ops.RRCr(p, 'D');},
0x0B: function(p){ops.RRCr(p, 'E');},
0x0C: function(p){ops.RRCr(p, 'H');},
0x0D: function(p){ops.RRCr(p, 'L');},
0x0E: function(p){ops.RRCrra(p, 'H', 'L');},
0x0F: function(p){ops.RRCr(p, 'A');},
0x10: function(p){ops.RLr(p, 'B');},
0x11: function(p){ops.RLr(p, 'C');},
0x12: function(p){ops.RLr(p, 'D');},
0x13: function(p){ops.RLr(p, 'E');},
0x14: function(p){ops.RLr(p, 'H');},
0x15: function(p){ops.RLr(p, 'L');},
0x16: function(p){ops.RLrra(p, 'H', 'L');},
0x17: function(p){ops.RLr(p, 'A');},
0x18: function(p){ops.RRr(p, 'B');},
0x19: function(p){ops.RRr(p, 'C');},
0x1A: function(p){ops.RRr(p, 'D');},
0x1B: function(p){ops.RRr(p, 'E');},
0x1C: function(p){ops.RRr(p, 'H');},
0x1D: function(p){ops.RRr(p, 'L');},
0x1E: function(p){ops.RRrra(p, 'H', 'L');},
0x1F: function(p){ops.RRr(p, 'A');},
0x20: function(p){ops.SLAr(p, 'B');},
0x21: function(p){ops.SLAr(p, 'C');},
0x22: function(p){ops.SLAr(p, 'D');},
0x23: function(p){ops.SLAr(p, 'E');},
0x24: function(p){ops.SLAr(p, 'H');},
0x25: function(p){ops.SLAr(p, 'L');},
0x26: function(p){ops.SLArra(p, 'H', 'L');},
0x27: function(p){ops.SLAr(p, 'A');},
0x28: function(p){ops.SRAr(p, 'B');},
0x29: function(p){ops.SRAr(p, 'C');},
0x2A: function(p){ops.SRAr(p, 'D');},
0x2B: function(p){ops.SRAr(p, 'E');},
0x2C: function(p){ops.SRAr(p, 'H');},
0x2D: function(p){ops.SRAr(p, 'L');},
0x2E: function(p){ops.SRArra(p, 'H', 'L');},
0x2F: function(p){ops.SRAr(p, 'A');},
0x30: function(p){ops.SWAPr(p, 'B');},
0x31: function(p){ops.SWAPr(p, 'C');},
0x32: function(p){ops.SWAPr(p, 'D');},
0x33: function(p){ops.SWAPr(p, 'E');},
0x34: function(p){ops.SWAPr(p, 'H');},
0x35: function(p){ops.SWAPr(p, 'L');},
0x36: function(p){ops.SWAPrra(p, 'H', 'L');},
0x37: function(p){ops.SWAPr(p, 'A');},
0x38: function(p){ops.SRLr(p, 'B');},
0x39: function(p){ops.SRLr(p, 'C');},
0x3A: function(p){ops.SRLr(p, 'D');},
0x3B: function(p){ops.SRLr(p, 'E');},
0x3C: function(p){ops.SRLr(p, 'H');},
0x3D: function(p){ops.SRLr(p, 'L');},
0x3E: function(p){ops.SRLrra(p, 'H', 'L');},
0x3F: function(p){ops.SRLr(p, 'A');},
0x40: function(p){ops.BITir(p, 0, 'B');},
0x41: function(p){ops.BITir(p, 0, 'C');},
0x42: function(p){ops.BITir(p, 0, 'D');},
0x43: function(p){ops.BITir(p, 0, 'E');},
0x44: function(p){ops.BITir(p, 0, 'H');},
0x45: function(p){ops.BITir(p, 0, 'L');},
0x46: function(p){ops.BITirra(p, 0, 'H', 'L');},
0x47: function(p){ops.BITir(p, 0, 'A');},
0x48: function(p){ops.BITir(p, 1, 'B');},
0x49: function(p){ops.BITir(p, 1, 'C');},
0x4A: function(p){ops.BITir(p, 1, 'D');},
0x4B: function(p){ops.BITir(p, 1, 'E');},
0x4C: function(p){ops.BITir(p, 1, 'H');},
0x4D: function(p){ops.BITir(p, 1, 'L');},
0x4E: function(p){ops.BITirra(p, 1, 'H', 'L');},
0x4F: function(p){ops.BITir(p, 1, 'A');},
0x50: function(p){ops.BITir(p, 2, 'B');},
0x51: function(p){ops.BITir(p, 2, 'C');},
0x52: function(p){ops.BITir(p, 2, 'D');},
0x53: function(p){ops.BITir(p, 2, 'E');},
0x54: function(p){ops.BITir(p, 2, 'H');},
0x55: function(p){ops.BITir(p, 2, 'L');},
0x56: function(p){ops.BITirra(p, 2, 'H', 'L');},
0x57: function(p){ops.BITir(p, 2, 'A');},
0x58: function(p){ops.BITir(p, 3, 'B');},
0x59: function(p){ops.BITir(p, 3, 'C');},
0x5A: function(p){ops.BITir(p, 3, 'D');},
0x5B: function(p){ops.BITir(p, 3, 'E');},
0x5C: function(p){ops.BITir(p, 3, 'H');},
0x5D: function(p){ops.BITir(p, 3, 'L');},
0x5E: function(p){ops.BITirra(p, 3, 'H', 'L');},
0x5F: function(p){ops.BITir(p, 3, 'A');},
0x60: function(p){ops.BITir(p, 4, 'B');},
0x61: function(p){ops.BITir(p, 4, 'C');},
0x62: function(p){ops.BITir(p, 4, 'D');},
0x63: function(p){ops.BITir(p, 4, 'E');},
0x64: function(p){ops.BITir(p, 4, 'H');},
0x65: function(p){ops.BITir(p, 4, 'L');},
0x66: function(p){ops.BITirra(p, 4, 'H', 'L');},
0x67: function(p){ops.BITir(p, 4, 'A');},
0x68: function(p){ops.BITir(p, 5, 'B');},
0x69: function(p){ops.BITir(p, 5, 'C');},
0x6A: function(p){ops.BITir(p, 5, 'D');},
0x6B: function(p){ops.BITir(p, 5, 'E');},
0x6C: function(p){ops.BITir(p, 5, 'H');},
0x6D: function(p){ops.BITir(p, 5, 'L');},
0x6E: function(p){ops.BITirra(p, 5, 'H', 'L');},
0x6F: function(p){ops.BITir(p, 5, 'A');},
0x70: function(p){ops.BITir(p, 6, 'B');},
0x71: function(p){ops.BITir(p, 6, 'C');},
0x72: function(p){ops.BITir(p, 6, 'D');},
0x73: function(p){ops.BITir(p, 6, 'E');},
0x74: function(p){ops.BITir(p, 6, 'H');},
0x75: function(p){ops.BITir(p, 6, 'L');},
0x76: function(p){ops.BITirra(p, 6, 'H', 'L');},
0x77: function(p){ops.BITir(p, 6, 'A');},
0x78: function(p){ops.BITir(p, 7, 'B');},
0x79: function(p){ops.BITir(p, 7, 'C');},
0x7A: function(p){ops.BITir(p, 7, 'D');},
0x7B: function(p){ops.BITir(p, 7, 'E');},
0x7C: function(p){ops.BITir(p, 7, 'H');},
0x7D: function(p){ops.BITir(p, 7, 'L');},
0x7E: function(p){ops.BITirra(p, 7, 'H', 'L');},
0x7F: function(p){ops.BITir(p, 7, 'A');},
0x80: function(p){ops.RESir(p, 0, 'B');},
0x81: function(p){ops.RESir(p, 0, 'C');},
0x82: function(p){ops.RESir(p, 0, 'D');},
0x83: function(p){ops.RESir(p, 0, 'E');},
0x84: function(p){ops.RESir(p, 0, 'H');},
0x85: function(p){ops.RESir(p, 0, 'L');},
0x86: function(p){ops.RESirra(p, 0, 'H', 'L');},
0x87: function(p){ops.RESir(p, 0, 'A');},
0x88: function(p){ops.RESir(p, 1, 'B');},
0x89: function(p){ops.RESir(p, 1, 'C');},
0x8A: function(p){ops.RESir(p, 1, 'D');},
0x8B: function(p){ops.RESir(p, 1, 'E');},
0x8C: function(p){ops.RESir(p, 1, 'H');},
0x8D: function(p){ops.RESir(p, 1, 'L');},
0x8E: function(p){ops.RESirra(p, 1, 'H', 'L');},
0x8F: function(p){ops.RESir(p, 1, 'A');},
0x90: function(p){ops.RESir(p, 2, 'B');},
0x91: function(p){ops.RESir(p, 2, 'C');},
0x92: function(p){ops.RESir(p, 2, 'D');},
0x93: function(p){ops.RESir(p, 2, 'E');},
0x94: function(p){ops.RESir(p, 2, 'H');},
0x95: function(p){ops.RESir(p, 2, 'L');},
0x96: function(p){ops.RESirra(p, 2, 'H', 'L');},
0x97: function(p){ops.RESir(p, 2, 'A');},
0x98: function(p){ops.RESir(p, 3, 'B');},
0x99: function(p){ops.RESir(p, 3, 'C');},
0x9A: function(p){ops.RESir(p, 3, 'D');},
0x9B: function(p){ops.RESir(p, 3, 'E');},
0x9C: function(p){ops.RESir(p, 3, 'H');},
0x9D: function(p){ops.RESir(p, 3, 'L');},
0x9E: function(p){ops.RESirra(p, 3, 'H', 'L');},
0x9F: function(p){ops.RESir(p, 3, 'A');},
0xA0: function(p){ops.RESir(p, 4, 'B');},
0xA1: function(p){ops.RESir(p, 4, 'C');},
0xA2: function(p){ops.RESir(p, 4, 'D');},
0xA3: function(p){ops.RESir(p, 4, 'E');},
0xA4: function(p){ops.RESir(p, 4, 'H');},
0xA5: function(p){ops.RESir(p, 4, 'L');},
0xA6: function(p){ops.RESirra(p, 4, 'H', 'L');},
0xA7: function(p){ops.RESir(p, 4, 'A');},
0xA8: function(p){ops.RESir(p, 5, 'B');},
0xA9: function(p){ops.RESir(p, 5, 'C');},
0xAA: function(p){ops.RESir(p, 5, 'D');},
0xAB: function(p){ops.RESir(p, 5, 'E');},
0xAC: function(p){ops.RESir(p, 5, 'H');},
0xAD: function(p){ops.RESir(p, 5, 'L');},
0xAE: function(p){ops.RESirra(p, 5, 'H', 'L');},
0xAF: function(p){ops.RESir(p, 5, 'A');},
0xB0: function(p){ops.RESir(p, 6, 'B');},
0xB1: function(p){ops.RESir(p, 6, 'C');},
0xB2: function(p){ops.RESir(p, 6, 'D');},
0xB3: function(p){ops.RESir(p, 6, 'E');},
0xB4: function(p){ops.RESir(p, 6, 'H');},
0xB5: function(p){ops.RESir(p, 6, 'L');},
0xB6: function(p){ops.RESirra(p, 6, 'H', 'L');},
0xB7: function(p){ops.RESir(p, 6, 'A');},
0xB8: function(p){ops.RESir(p, 7, 'B');},
0xB9: function(p){ops.RESir(p, 7, 'C');},
0xBA: function(p){ops.RESir(p, 7, 'D');},
0xBB: function(p){ops.RESir(p, 7, 'E');},
0xBC: function(p){ops.RESir(p, 7, 'H');},
0xBD: function(p){ops.RESir(p, 7, 'L');},
0xBE: function(p){ops.RESirra(p, 7, 'H', 'L');},
0xBF: function(p){ops.RESir(p, 7, 'A');},
0xC0: function(p){ops.SETir(p, 0, 'B');},
0xC1: function(p){ops.SETir(p, 0, 'C');},
0xC2: function(p){ops.SETir(p, 0, 'D');},
0xC3: function(p){ops.SETir(p, 0, 'E');},
0xC4: function(p){ops.SETir(p, 0, 'H');},
0xC5: function(p){ops.SETir(p, 0, 'L');},
0xC6: function(p){ops.SETirra(p, 0, 'H', 'L');},
0xC7: function(p){ops.SETir(p, 0, 'A');},
0xC8: function(p){ops.SETir(p, 1, 'B');},
0xC9: function(p){ops.SETir(p, 1, 'C');},
0xCA: function(p){ops.SETir(p, 1, 'D');},
0xCB: function(p){ops.SETir(p, 1, 'E');},
0xCC: function(p){ops.SETir(p, 1, 'H');},
0xCD: function(p){ops.SETir(p, 1, 'L');},
0xCE: function(p){ops.SETirra(p, 1, 'H', 'L');},
0xCF: function(p){ops.SETir(p, 1, 'A');},
0xD0: function(p){ops.SETir(p, 2, 'B');},
0xD1: function(p){ops.SETir(p, 2, 'C');},
0xD2: function(p){ops.SETir(p, 2, 'D');},
0xD3: function(p){ops.SETir(p, 2, 'E');},
0xD4: function(p){ops.SETir(p, 2, 'H');},
0xD5: function(p){ops.SETir(p, 2, 'L');},
0xD6: function(p){ops.SETirra(p, 2, 'H', 'L');},
0xD7: function(p){ops.SETir(p, 2, 'A');},
0xD8: function(p){ops.SETir(p, 3, 'B');},
0xD9: function(p){ops.SETir(p, 3, 'C');},
0xDA: function(p){ops.SETir(p, 3, 'D');},
0xDB: function(p){ops.SETir(p, 3, 'E');},
0xDC: function(p){ops.SETir(p, 3, 'H');},
0xDD: function(p){ops.SETir(p, 3, 'L');},
0xDE: function(p){ops.SETirra(p, 3, 'H', 'L');},
0xDF: function(p){ops.SETir(p, 3, 'A');},
0xE0: function(p){ops.SETir(p, 4, 'B');},
0xE1: function(p){ops.SETir(p, 4, 'C');},
0xE2: function(p){ops.SETir(p, 4, 'D');},
0xE3: function(p){ops.SETir(p, 4, 'E');},
0xE4: function(p){ops.SETir(p, 4, 'H');},
0xE5: function(p){ops.SETir(p, 4, 'L');},
0xE6: function(p){ops.SETirra(p, 4, 'H', 'L');},
0xE7: function(p){ops.SETir(p, 4, 'A');},
0xE8: function(p){ops.SETir(p, 5, 'B');},
0xE9: function(p){ops.SETir(p, 5, 'C');},
0xEA: function(p){ops.SETir(p, 5, 'D');},
0xEB: function(p){ops.SETir(p, 5, 'E');},
0xEC: function(p){ops.SETir(p, 5, 'H');},
0xED: function(p){ops.SETir(p, 5, 'L');},
0xEE: function(p){ops.SETirra(p, 5, 'H', 'L');},
0xEF: function(p){ops.SETir(p, 5, 'A');},
0xF0: function(p){ops.SETir(p, 6, 'B');},
0xF1: function(p){ops.SETir(p, 6, 'C');},
0xF2: function(p){ops.SETir(p, 6, 'D');},
0xF3: function(p){ops.SETir(p, 6, 'E');},
0xF4: function(p){ops.SETir(p, 6, 'H');},
0xF5: function(p){ops.SETir(p, 6, 'L');},
0xF6: function(p){ops.SETirra(p, 6, 'H', 'L');},
0xF7: function(p){ops.SETir(p, 6, 'A');},
0xF8: function(p){ops.SETir(p, 7, 'B');},
0xF9: function(p){ops.SETir(p, 7, 'C');},
0xFA: function(p){ops.SETir(p, 7, 'D');},
0xFB: function(p){ops.SETir(p, 7, 'E');},
0xFC: function(p){ops.SETir(p, 7, 'H');},
0xFD: function(p){ops.SETir(p, 7, 'L');},
0xFE: function(p){ops.SETirra(p, 7, 'H', 'L');},
0xFF: function(p){ops.SETir(p, 7, 'A');}
};
GameboyJS.opcodeMap = map;
GameboyJS.opcodeCbmap = cbmap;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,36 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// A RomAjaxReader is able to load a file through an AJAX request
var RomAjaxReader = function() {
};
// The callback argument will be called when a file is successfully
// read, with the data as argument (Uint8Array)
RomAjaxReader.prototype.setCallback = function(onLoadCallback) {
this.callback = onLoadCallback;
};
// This function should be called by application code
// and will trigger the AJAX call itself and push data to the ROM object
RomAjaxReader.prototype.loadFromUrl = function(url) {
if (!url) {
throw 'No url has been set in order to load a ROM file.';
}
var cb = this.callback;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = "arraybuffer";
xhr.onload = function() {
var rom = new Uint8Array(xhr.response);
cb && cb(rom);
};
xhr.send();
};
GameboyJS.RomAjaxReader = RomAjaxReader;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,65 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// A RomDropFileReader is able to load a drag and dropped file
var RomDropFileReader = function(el) {
this.dropElement = el;
if (!this.dropElement) {
throw 'The RomDropFileReader needs a drop zone.';
}
var self = this;
this.dropElement.addEventListener('dragenter', function(e) {
e.preventDefault();
if (e.target !== self.dropElement) {
return;
}
self.dropElement.classList.add('drag-active');
});
this.dropElement.addEventListener('dragleave', function(e) {
e.preventDefault();
if (e.target !== self.dropElement) {
return;
}
self.dropElement.classList.remove('drag-active');
});
this.dropElement.addEventListener('dragover', function(e) {
e.preventDefault();
self.dropElement.classList.add('drag-active');
});
this.dropElement.addEventListener('drop', function (e) {
self.dropElement.classList.remove('drag-active');
if (e.dataTransfer.files.length == 0) {
return;
}
e.preventDefault();
self.loadFromFile(e.dataTransfer.files[0]);
});
};
// The callback argument will be called when a file is successfully
// read, with the data as argument (Uint8Array)
RomDropFileReader.prototype.setCallback = function(onLoadCallback) {
this.callback = onLoadCallback;
};
// The file loading logic is the same as the regular file reader
RomDropFileReader.prototype.loadFromFile = function(file) {
if (file === undefined) {
return;
}
var fr = new FileReader();
var cb = this.callback;
fr.onload = function() {
cb && cb(new Uint8Array(fr.result));
};
fr.onerror = function(e) {
console.log('Error reading the file', e.target.error.code)
};
fr.readAsArrayBuffer(file);
};
GameboyJS.RomDropFileReader = RomDropFileReader;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,45 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// A RomFileReader is able to load a local file from an input element
//
// Expects to be provided a file input element,
// or will try to find one with the "file" DOM ID
var RomFileReader = function(el) {
this.domElement = el || document.getElementById('file');
if (!this.domElement) {
throw 'The RomFileReader needs a valid input element.';
}
var self = this;
this.domElement.addEventListener('change', function(e){
self.loadFromFile(e.target.files[0]);
});
};
// The callback argument will be called when a file is successfully
// read, with the data as argument (Uint8Array)
RomFileReader.prototype.setCallback = function(onLoadCallback) {
this.callback = onLoadCallback;
};
// Automatically called when the DOM input is provided with a file
RomFileReader.prototype.loadFromFile = function(file) {
if (file === undefined) {
return;
}
var fr = new FileReader();
var cb = this.callback;
fr.onload = function() {
cb && cb(new Uint8Array(fr.result));
};
fr.onerror = function(e) {
console.log('Error reading the file', e.target.error.code)
};
fr.readAsArrayBuffer(file);
};
GameboyJS.RomFileReader = RomFileReader;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,35 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
var Rom = function(gameboy, romReader) {
this.gameboy = gameboy;
if (romReader) {
this.addReader(romReader);
}
};
Rom.prototype.addReader = function(romReader) {
var self = this;
romReader.setCallback(function(data) {
if (!validate(data)) {
self.gameboy.error('The file is not a valid GameBoy ROM.');
return;
}
self.data = data;
self.gameboy.startRom(self);
});
};
// Validate the checksum of the cartridge header
function validate(data) {
var hash = 0;
for (var i = 0x134; i <= 0x14C; i++) {
hash = hash - data[i] - 1;
}
return (hash & 0xFF) == data[0x14D];
};
GameboyJS.Rom = Rom;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,43 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// Handlers for the Serial port of the Gameboy
// The ConsoleSerial is an output-only serial port
// designed for debug purposes as some test roms output data on the serial port
//
// Will regularly output the received byte (converted to string) in the console logs
// This handler always push the value 0xFF as an input
var ConsoleSerial = {
current: '',
timeout: null,
out: function(data) {
ConsoleSerial.current += String.fromCharCode(data);
if (data == 10) {
ConsoleSerial.print();
} else {
clearTimeout(ConsoleSerial.timeout);
ConsoleSerial.timeout = setTimeout(ConsoleSerial.print, 500);
}
},
in: function() {
return 0xFF;
},
print: function() {
clearTimeout(ConsoleSerial.timeout);
console.log('serial: '+ConsoleSerial.current);
ConsoleSerial.current = '';
}
};
GameboyJS.ConsoleSerial = ConsoleSerial;
// A DummySerial outputs nothing and always inputs 0xFF
var DummySerial = {
out: function() {},
in: function() {
return 0xFF;
}
};
GameboyJS.DummySerial = DummySerial;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,212 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
// Audio Processing unit
// Listens the write accesses to the audio-reserved memory addresses
// and dispatches the data to the sound channels
var APU = function(memory) {
this.memory = memory;
this.enabled = false;
var AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContext();
this.channel1 = new GameboyJS.Channel1(this, 1, audioContext);
this.channel2 = new GameboyJS.Channel1(this, 2, audioContext);
this.channel3 = new GameboyJS.Channel3(this, 3, audioContext);
this.channel4 = new GameboyJS.Channel4(this, 4, audioContext);
};
APU.prototype.connect = function() {
this.channel1.enable();
this.channel2.enable();
this.channel3.enable();
};
APU.prototype.disconnect = function() {
this.channel1.disable();
this.channel2.disable();
this.channel3.disable();
};
// Updates the states of each channel given the elapsed time
// (in instructions) since last update
APU.prototype.update = function(clockElapsed) {
if (this.enabled == false) return;
this.channel1.update(clockElapsed);
this.channel2.update(clockElapsed);
this.channel3.update(clockElapsed);
this.channel4.update(clockElapsed);
};
APU.prototype.setSoundFlag = function(channel, value) {
var mask = 0xFF - (1 << (channel - 1));
value = value << (channel - 1)
var byteValue = this.memory.rb(APU.registers.NR52);
byteValue &= mask;
byteValue |= value;
this.memory[APU.registers.NR52] = byteValue;
};
// Manage writes to audio registers
// Will update the channels depending on the address
APU.prototype.manageWrite = function(addr, value) {
if (this.enabled == false && addr < APU.registers.NR52) {
return;
}
this.memory[addr] = value;
switch (addr) {
// Channel 1 addresses
case 0xFF10:
this.channel1.clockSweep = 0;
this.channel1.sweepTime = ((value & 0x70) >> 4);
this.channel1.sweepSign = (value & 0x08) ? -1 : 1;
this.channel1.sweepShifts = (value & 0x07);
this.channel1.sweepCount = this.channel1.sweepShifts;
break;
case 0xFF11:
// todo : bits 6-7
this.channel1.setLength(value & 0x3F);
break;
case 0xFF12:
this.channel1.envelopeSign = (value & 0x08) ? 1 : -1;
var envelopeVolume = (value & 0xF0) >> 4;
this.channel1.setEnvelopeVolume(envelopeVolume);
this.channel1.envelopeStep = (value & 0x07);
break;
case 0xFF13:
var frequency = this.channel1.getFrequency();
frequency &= 0xF00;
frequency |= value;
this.channel1.setFrequency(frequency);
break;
case 0xFF14:
var frequency = this.channel1.getFrequency();
frequency &= 0xFF;
frequency |= (value & 7) << 8;
this.channel1.setFrequency(frequency);
this.channel1.lengthCheck = (value & 0x40) ? true : false;
if (value & 0x80) this.channel1.play();
break;
// Channel 2 addresses
case 0xFF16:
// todo : bits 6-7
this.channel2.setLength(value & 0x3F);
break;
case 0xFF17:
this.channel2.envelopeSign = (value & 0x08) ? 1 : -1;
var envelopeVolume = (value & 0xF0) >> 4;
this.channel2.setEnvelopeVolume(envelopeVolume);
this.channel2.envelopeStep = (value & 0x07);
break;
case 0xFF18:
var frequency = this.channel2.getFrequency();
frequency &= 0xF00;
frequency |= value;
this.channel2.setFrequency(frequency);
break;
case 0xFF19:
var frequency = this.channel2.getFrequency();
frequency &= 0xFF;
frequency |= (value & 7) << 8;
this.channel2.setFrequency(frequency);
this.channel2.lengthCheck = (value & 0x40) ? true : false;
if (value & 0x80) {
this.channel2.play();
}
break;
// Channel 3 addresses
case 0xFF1A:
// todo
break;
case 0xFF1B:
this.channel3.setLength(value);
break;
case 0xFF1C:
// todo
break;
case 0xFF1D:
var frequency = this.channel3.getFrequency();
frequency &= 0xF00;
frequency |= value;
this.channel3.setFrequency(frequency);
break;
case 0xFF1E:
var frequency = this.channel3.getFrequency();
frequency &= 0xFF;
frequency |= (value & 7) << 8;
this.channel3.setFrequency(frequency);
this.channel3.lengthCheck = (value & 0x40) ? true : false;
if (value & 0x80) {
this.channel3.play();
}
break;
// Channel 4 addresses
case 0xFF20:
this.channel4.setLength(value & 0x3F);
break;
case 0xFF21:
// todo
break;
case 0xFF22:
// todo
break;
case 0xFF23:
this.channel4.lengthCheck = (value & 0x40) ? true : false;
if (value & 0x80) {
this.channel4.play();
}
break;
// channel 3 wave bytes
case 0xFF30:case 0xFF31:case 0xFF32:case 0xFF33:case 0xFF34:case 0xFF35:case 0xFF36:case 0xFF37:
case 0xFF38:case 0xFF39:case 0xFF3A:case 0xFF3B:case 0xFF3C:case 0xFF3D:case 0xFF3E:case 0xFF3F:
var index = addr - 0xFF30;
this.channel3.setWaveBufferByte(index, value);
break;
// general audio switch
case 0xFF26:
value &= 0xF0;
this.memory[addr] = value;
this.enabled = (value & 0x80) == 0 ? false : true;
if (!this.enabled) {
for (var i = 0xFF10; i < 0xFF27; i++)
this.memory[i] = 0;
// todo stop sound
}
break;
}
};
APU.registers = {
NR10: 0xFF10,
NR11: 0xFF11,
NR12: 0xFF12,
NR13: 0xFF13,
NR14: 0xFF14,
NR21: 0xFF16,
NR22: 0xFF17,
NR23: 0xFF18,
NR24: 0xFF19,
NR30: 0xFF1A,
NR31: 0xFF1B,
NR32: 0xFF1C,
NR33: 0xFF1D,
NR34: 0xFF1E,
NR41: 0xFF20,
NR42: 0xFF21,
NR43: 0xFF22,
NR44: 0xFF23,
NR50: 0xFF24,
NR51: 0xFF25,
NR52: 0xFF26
};
GameboyJS.APU = APU;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,129 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
var Channel1 = function(apu, channelNumber, audioContext) {
this.apu = apu;
this.channelNumber = channelNumber;
this.playing = false;
this.soundLengthUnit = 0x4000; // 1 / 256 second of instructions
this.soundLength = 64; // defaults to 64 periods
this.lengthCheck = false;
this.sweepTime = 0; // from 0 to 7
this.sweepStepLength = 0x8000; // 1 / 128 seconds of instructions
this.sweepCount = 0;
this.sweepShifts = 0;
this.sweepSign = 1; // +1 / -1 for increase / decrease freq
this.frequency = 0;
this.envelopeStep = 0;
this.envelopeStepLength = 0x10000;// 1 / 64 seconds of instructions
this.envelopeCheck = false;
this.envelopeSign = 1;
this.clockLength = 0;
this.clockEnvelop = 0;
this.clockSweep = 0;
var gainNode = audioContext.createGain();
gainNode.gain.value = 0;
var oscillator = audioContext.createOscillator();
oscillator.type = 'square';
oscillator.frequency.value = 1000;
oscillator.connect(gainNode);
oscillator.start(0);
this.audioContext = audioContext;
this.gainNode = gainNode;
this.oscillator = oscillator;
};
Channel1.prototype.play = function() {
if (this.playing) return;
this.playing = true;
this.apu.setSoundFlag(this.channelNumber, 1);
this.gainNode.connect(this.audioContext.destination);
this.clockLength = 0;
this.clockEnvelop = 0;
this.clockSweep = 0;
if (this.sweepShifts > 0) this.checkFreqSweep();
};
Channel1.prototype.stop = function() {
this.playing = false;
this.apu.setSoundFlag(this.channelNumber, 0);
this.gainNode.disconnect();
};
Channel1.prototype.checkFreqSweep = function() {
var oldFreq = this.getFrequency();
var newFreq = oldFreq + this.sweepSign * (oldFreq >> this.sweepShifts);
if (newFreq > 0x7FF) {
newFreq = 0;
this.stop();
}
return newFreq;
};
Channel1.prototype.update = function(clockElapsed) {
this.clockEnvelop += clockElapsed;
this.clockSweep += clockElapsed;
if ((this.sweepCount || this.sweepTime) && this.clockSweep > (this.sweepStepLength * this.sweepTime)) {
this.clockSweep -= (this.sweepStepLength * this.sweepTime);
this.sweepCount--;
var newFreq = this.checkFreqSweep(); // process and check new freq
this.apu.memory[0xFF13] = newFreq & 0xFF;
this.apu.memory[0xFF14] &= 0xF8;
this.apu.memory[0xFF14] |= (newFreq & 0x700) >> 8;
this.setFrequency(newFreq);
this.checkFreqSweep(); // check again with new value
}
if (this.envelopeCheck && this.clockEnvelop > this.envelopeStepLength) {
this.clockEnvelop -= this.envelopeStepLength;
this.envelopeStep--;
this.setEnvelopeVolume(this.envelopeVolume + this.envelopeSign);
if (this.envelopeStep <= 0) {
this.envelopeCheck = false;
}
}
if (this.lengthCheck) {
this.clockLength += clockElapsed;
if (this.clockLength > this.soundLengthUnit) {
this.soundLength--;
this.clockLength -= this.soundLengthUnit;
if (this.soundLength == 0) {
this.setLength(0);
this.stop();
}
}
}
};
Channel1.prototype.setFrequency = function(value) {
this.frequency = value;
this.oscillator.frequency.value = 131072 / (2048 - this.frequency);
};
Channel1.prototype.getFrequency = function() {
return this.frequency;
};
Channel1.prototype.setLength = function(value) {
this.soundLength = 64 - (value & 0x3F);
};
Channel1.prototype.setEnvelopeVolume = function(volume) {
this.envelopeCheck = volume > 0 && volume < 16 ? true : false;
this.envelopeVolume = volume;
this.gainNode.gain.value = this.envelopeVolume * 1/100;
};
Channel1.prototype.disable = function() {
this.oscillator.disconnect();
};
Channel1.prototype.enable = function() {
this.oscillator.connect(this.gainNode);
};
GameboyJS.Channel1 = Channel1;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,86 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
var Channel3 = function(apu, channelNumber, audioContext) {
this.apu = apu;
this.channelNumber = channelNumber;
this.playing = false;
this.soundLength = 0;
this.soundLengthUnit = 0x4000; // 1 / 256 second of instructions
this.lengthCheck = false;
this.clockLength = 0;
this.buffer = new Float32Array(32);
var gainNode = audioContext.createGain();
gainNode.gain.value = 1;
this.gainNode = gainNode;
this.baseSpeed = 65536;
var waveBuffer = audioContext.createBuffer(1, 32, this.baseSpeed);
var bufferSource = audioContext.createBufferSource();
bufferSource.buffer = waveBuffer;
bufferSource.loop = true;
bufferSource.connect(gainNode);
bufferSource.start(0);
this.audioContext = audioContext;
this.waveBuffer = waveBuffer;
this.bufferSource = bufferSource;
};
Channel3.prototype.play = function() {
if (this.playing) return;
this.playing = true;
this.apu.setSoundFlag(this.channelNumber, 1);
this.waveBuffer.copyToChannel(this.buffer, 0, 0);
this.gainNode.connect(this.audioContext.destination);
this.clockLength = 0;
};
Channel3.prototype.stop = function() {
this.playing = false;
this.apu.setSoundFlag(this.channelNumber, 0);
this.gainNode.disconnect();
};
Channel3.prototype.update = function(clockElapsed) {
if (this.lengthCheck){
this.clockLength += clockElapsed;
if (this.clockLength > this.soundLengthUnit) {
this.soundLength--;
this.clockLength -= this.soundLengthUnit;
if (this.soundLength == 0) {
this.setLength(0);
this.stop();
}
}
}
};
Channel3.prototype.setFrequency = function(value) {
value = 65536 / (2048 - value);
this.bufferSource.playbackRate.value = value / this.baseSpeed;
};
Channel3.prototype.getFrequency = function() {
var freq = 2048 - 65536 / (this.bufferSource.playbackRate.value * this.baseSpeed);
return freq | 1;
};
Channel3.prototype.setLength = function(value) {
this.soundLength = 256 - value;
};
Channel3.prototype.setWaveBufferByte = function(index, value) {
var bufferIndex = index * 2;
this.buffer[bufferIndex] = (value >> 4) / 8 - 1; // value in buffer is in -1 -> 1
this.buffer[bufferIndex+1] = (value & 0x0F) / 8 - 1;
};
Channel3.prototype.disable = function() {
this.bufferSource.disconnect();
};
Channel3.prototype.enable = function() {
this.bufferSource.connect(this.gainNode);
};
GameboyJS.Channel3 = Channel3;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,45 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
var Channel4 = function(apu, channelNumber, audioContext) {
this.apu = apu;
this.channelNumber = channelNumber;
this.playing = false;
this.soundLengthUnit = 0x4000; // 1 / 256 second of instructions
this.soundLength = 64; // defaults to 64 periods
this.lengthCheck = false;
this.clockLength = 0;
this.audioContext = audioContext;
};
Channel4.prototype.play = function() {
if (this.playing) return;
this.playing = true;
this.apu.setSoundFlag(this.channelNumber, 1);
this.clockLength = 0;
};
Channel4.prototype.stop = function() {
this.playing = false;
this.apu.setSoundFlag(this.channelNumber, 0);
};
Channel4.prototype.update = function(clockElapsed) {
if (this.lengthCheck) {
this.clockLength += clockElapsed;
if (this.clockLength > this.soundLengthUnit) {
this.soundLength--;
this.clockLength -= this.soundLengthUnit;
if (this.soundLength == 0) {
this.setLength(0);
this.stop();
}
}
}
};
Channel4.prototype.setLength = function(value) {
this.soundLength = 64 - (value & 0x3F);
};
GameboyJS.Channel4 = Channel4;
}(GameboyJS || (GameboyJS = {})));

View file

@ -1,66 +0,0 @@
var GameboyJS;
(function (GameboyJS) {
"use strict";
var Timer = function(cpu, memory) {
this.cpu = cpu;
this.memory = memory;
this.DIV = 0xFF04;
this.TIMA = 0xFF05;
this.TMA = 0xFF06;
this.TAC = 0xFF07;
this.mainTime = 0;
this.divTime = 0;
};
Timer.prototype.update = function(clockElapsed) {
this.updateDiv(clockElapsed);
this.updateTimer(clockElapsed);
};
Timer.prototype.updateTimer = function(clockElapsed) {
if (!(this.memory.rb(this.TAC) & 0x4)) {
return;
}
this.mainTime += clockElapsed;
var threshold = 64;
switch (this.memory.rb(this.TAC) & 3) {
case 0: threshold=64; break; // 4KHz
case 1: threshold=1; break; // 256KHz
case 2: threshold=4; break; // 64KHz
case 3: threshold=16; break; // 16KHz
}
threshold *= 16;
while (this.mainTime >= threshold) {
this.mainTime -= threshold;
this.memory.wb(this.TIMA, this.memory.rb(this.TIMA) + 1);
if (this.memory.rb(this.TIMA) > 0xFF) {
this.memory.wb(this.TIMA, this.memory.rb(this.TMA));
this.cpu.requestInterrupt(GameboyJS.CPU.INTERRUPTS.TIMER);
}
}
};
// Update the DIV register internal clock
// Increment it if the clock threshold is elapsed and
// reset it if its value overflows
Timer.prototype.updateDiv = function(clockElapsed) {
var divThreshold = 256; // DIV is 16KHz
this.divTime += clockElapsed;
if (this.divTime > divThreshold) {
this.divTime -= divThreshold;
var div = this.memory.rb(this.DIV) + 1;
this.memory.wb(this.DIV, div&0xFF);
}
};
Timer.prototype.resetDiv = function() {
this.divTime = 0;
this.memory[this.DIV] = 0; // direct write to avoid looping
};
GameboyJS.Timer = Timer;
}(GameboyJS || (GameboyJS = {})));