summaryrefslogtreecommitdiff
path: root/www
diff options
context:
space:
mode:
Diffstat (limited to 'www')
-rw-r--r--www/css/anim.css16
-rw-r--r--www/css/index.css14
-rw-r--r--www/index.html21
-rw-r--r--www/js/api.js104
-rw-r--r--www/js/html5ks.js335
-rw-r--r--www/js/menu.js33
6 files changed, 335 insertions, 188 deletions
diff --git a/www/css/anim.css b/www/css/anim.css
index ee2889d..e89959d 100644
--- a/www/css/anim.css
+++ b/www/css/anim.css
@@ -22,3 +22,19 @@
0% { opacity: 1; }
100% { opacity: 0; }
}
+
+@-webkit-keyframes blink {
+ 0% { opacity: 0; }
+ 50% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+@-moz-keyframes blink {
+ 0% { opacity: 0; }
+ 50% { opacity: 1; }
+ 100% { opacity: 0; }
+}
+@keyframes blink {
+ 0% { opacity: 0; }
+ 50% { opacity: 1; }
+ 100% { opacity: 0; }
+}
diff --git a/www/css/index.css b/www/css/index.css
index 533559c..e5a5c19 100644
--- a/www/css/index.css
+++ b/www/css/index.css
@@ -27,6 +27,8 @@ body {
#container, #bg, #vid {
cursor: url("../dump/ui/mousecursor.png"), default;
position: absolute;
+}
+#container.scale, #bg.scale, #vid.scale {
top: 50%;
left: 50%;
}
@@ -96,7 +98,6 @@ html.no-js #warn-container {
h2 {
font: 20px/28px Playtime;
font-weight: bold;
- opacity: 0.4;
}
html.no-js #warn li:not(#js) { display: none; }
#warn li#ie { display: none; }
@@ -109,8 +110,7 @@ html #warn li#html-svg-filter { display: none; }
label {
display: block;
}
-.button-enabled {
-/* cursor: pointer; */
+.button, h2, label {
opacity: 0.4;
}
.button-disabled {
@@ -141,3 +141,11 @@ input[type="checkbox"] + span:before {
input[type="checkbox"]:checked + span:before {
background: url("../dump/ui/bt-cf-checked.png") no-repeat left bottom;
}
+#ctc {
+ position: absolute;
+ bottom: 20px;
+ right: 10px;
+ -webkit-animation: blink 2s infinite;
+ -moz-animation: blink 2s infinite;
+ animation: blink 2s infinite;
+}
diff --git a/www/index.html b/www/index.html
index 19b109c..b01fea4 100644
--- a/www/index.html
+++ b/www/index.html
@@ -49,6 +49,7 @@
<img id="window-image" src="dump/ui/bg-say.png" alt="">
<div id="who"></div>
<div id="say"></div>
+ <img id="ctc" src="dump/ui/ctc.png" style="display: none">
</div>
<div id="main-menu" style="display: none;">
<div id="main-menu-buttons" style="top: 377px; position: absolute; left: 81px;">
@@ -67,18 +68,18 @@
<div id="dialogs" style="display: none; position: absolute; top: 50%; width: 504px; height: 395px; background: url(dump/ui/bg-config.png); left: 50%; margin-left: -252px; margin-top: -197.5px;">
<div id="options" style="padding: 10px 20px;">
<h2>Options</h2>
- <label class="button button-enabled"><input type="checkbox" id="hdisable"> <span>Disable adult content</span></label>
- <label class="button button-enabled"><input type="checkbox" id="fullscreen"> <span>Fullscreen mode</span></label>
- <label class="button button-enabled"><input type="checkbox" id="skip-unread"> <span>Skip unread text</span></label>
- <label class="button button-enabled"><input type="checkbox" id="skip-after-choices"> <span>Keep skipping after choices</span></label>
- <label class="button button-enabled"><input type="checkbox" id="use-webp"> <span>Use WebP images (less bandwidth, more CPU)</span></label>
- <label class="button button-enabled"><input type="checkbox" id="scale-video"> <span>Scale video to fullscreen (decreases performance)</span></label>
+ <label class="button button-enabled"><input type="checkbox" class="option" id="hdisable"> <span>Disable adult content</span></label>
+ <label class="button button-enabled"><input type="checkbox" class="option" id="skipUnread"> <span>Skip unread text</span></label>
+ <label class="button button-enabled"><input type="checkbox" class="option" id="skipAfterChoices"> <span>Keep skipping after choices</span></label>
+ <label class="button button-enabled"><input type="checkbox" class="option" id="useWebP"> <span>Use WebP images (less bandwidth, more CPU)</span></label>
+ <label class="button button-enabled"><input type="checkbox" class="option" id="fullscreen"> <span>Scale content</span></label>
+ <label class="button button-enabled"><input type="checkbox" class="option" id="scaleVideo"> <span>Scale video</span></label>
- <label><input type="range" id="text-speed"> <span class="tr">Text speed</span></label>
- <label><input type="range" id="auto-mode-delay"> <span class="tr">Auto mode delay</span></label>
+ <label><input type="range" min="0.0" max="1.0" step="0.001" class="option" id="textSpeed"> <span class="tr">Text speed</span></label>
+ <label><input type="range" min="0.0" max="1.0" step="0.001" class="option" id="autoModeDelay"> <span class="tr">Auto mode delay</span></label>
- <label><input type="range" id="music-volume"> <span class="tr">Music volume</span></label>
- <label><input type="range" id="sfx-volume"> <span class="tr">SFX volume</span> <span id="test-sfx" class="button button-enabled"><img src="dump/ui/bt-musicplay.png"> Test</span></label>
+ <label><input type="range" min="0.0" max="1.0" step="0.001" class="option" id="musicVolume"> <span class="tr">Music volume</span></label>
+ <label><input type="range" min="0.0" max="1.0" step="0.001" class="option" id="sfxVolume"> <span class="tr">SFX volume</span> <span id="test-sfx" class="button button-enabled"><img src="dump/ui/bt-musicplay.png"> Test</span></label>
</div>
<div id="return" class="button button-enabled" style="position: absolute; bottom: 15px; right: 20px;">
<img src="dump/ui/bt-return.png">
diff --git a/www/js/api.js b/www/js/api.js
index 128cd9c..1aec74d 100644
--- a/www/js/api.js
+++ b/www/js/api.js
@@ -1,5 +1,14 @@
"use strict";
window.html5ks.api = {
+ init: function () {
+ var chars = html5ks.data.characters;
+ for (var ch in chars) {
+ var char = chars[ch];
+ if (char.name) {
+ char.name = this.tag(char.name);
+ }
+ }
+ },
seen_scene: function (scene) {
return !!html5ks.persistent.seen_scenes[scene];
},
@@ -43,6 +52,11 @@ window.html5ks.api = {
return deferred.promise;
},
stop: function (channel, fade) {
+ if (channel === "all") {
+ this.stop("music");
+ this.stop("sound");
+ return this.stop("ambient");
+ }
var deferred = when.defer(),
audio = html5ks.elements.audio[channel],
fadeSet = html5ks.persistent.settings.fade;
@@ -68,6 +82,8 @@ window.html5ks.api = {
video.src = src + "mp4";
}
+ this.stop("all");
+
video.load();
video.style.display = "block";
video.play();
@@ -115,13 +131,13 @@ window.html5ks.api = {
var cmd = inst[0],
args = inst.slice(1);
if (html5ks.data.characters[cmd]) {
- return this.character(cmd, args);
+ return this.character(cmd, args[0]);
} else {
if (this[cmd]) {
return this[cmd].apply(this, args);
} else if (/^[A-Z]/.test(cmd)) {
console.log("cmd starts with caps, probably character");
- return this.character(cmd, args);
+ return this.character(cmd, args[0]);
} else {
console.error("no such cmd " + cmd);
var deferred = when.defer();
@@ -194,38 +210,92 @@ window.html5ks.api = {
return deferred.promise;
},
- character: function (name, str) {
+ tag: function (str) {
+ var tags = [
+ /&/g, "&amp;",
+ /</g, "&lt;",
+ />/g, "&gt;",
+ /{b}/g, "<b>",
+ /{\/b}/g, "</b>",
+ /{s}/g, "<s>",
+ /{\/s}/g, "</s>",
+ /{size=(\d*)}/g, "<span style='color: $1'>",
+ /{\/size}/g, "</span>",
+ /{color=(\d*)}/g, "<span style='color: $1'>",
+ /{\/color}/g, "</span>",
+ /{w(=\d*\.\d*)?}.*/, "",
+ /{nw}/, "",
+ /{fast}/, ""
+ ];
+ for (var i = 0; i < tags.length - 1; i += 2) {
+ str = str.replace(tags[i], tags[i+1]);
+ }
+ return str;
+ },
+
+ character: function (name, str, extend) {
var deferred = when.defer(),
- text = str,
- char = html5ks.data.characters[name];
+ text = this.tag(str),
+ char = html5ks.data.characters[name],
+ w = /{w(=\d*\.\d*)?}/.exec(str);
+
if (!char) {
char = { name: name };
}
- if (char.what_prefix) {
+ if (!extend && char.what_prefix) {
text = char.what_prefix + text;
}
- if (char.what_suffix) {
+ if ((!w || !w[1] || extend) && char.what_suffix) {
text = text + char.what_suffix;
}
var who = html5ks.elements.who;
- who.textContent = char.name;
- if (char.color) {
- who.style.color = char.color;
+ if (!extend) {
+ who.innerHTML = char.name;
+ if (char.color) {
+ who.style.color = char.color;
+ } else {
+ who.style.color = "#ffffff";
+ }
+ }
+
+ if (extend) {
+ html5ks.elements.say.innerHTML += text;
} else {
- who.style.color = "#ffffff";
+ html5ks.elements.say.innerHTML = text;
}
- html5ks.elements.say.textContent = text;
- html5ks.next = function () {
- deferred.resolve(text);
- html5ks.next = function () {};
- };
- if (html5ks.state.skip) {
+
+ if (w) {
+ html5ks.next = function () {
+ html5ks.next = function () {};
+ html5ks.api.extend(str.substring(w.index + w[0].length)).then(function () {
+ deferred.resolve();
+ });
+ };
+ if (w[1]) {
+ setTimeout(html5ks.next, parseFloat(w[1].substring(1), 10) * 1000);
+ return deferred.promise;
+ }
+ } else {
+ html5ks.next = function () {
+ html5ks.elements.ctc.style.display = "none";
+ deferred.resolve(text);
+ html5ks.next = function () {};
+ };
+ }
+ if (html5ks.state.skip || str.indexOf("{nw}") > -1) {
html5ks.next();
} else if (html5ks.state.auto) {
setTimeout(html5ks.next, 1000 + html5ks.persistent.settings.autospeed * text.length);
+ } else {
+ html5ks.elements.ctc.style.display = "block";
}
return deferred.promise;
},
+
+ extend: function (str) {
+ return this.character(null, str, true);
+ },
+
Pause: function (duration) {
var deferred = when.defer();
setTimeout(function () {
diff --git a/www/js/html5ks.js b/www/js/html5ks.js
index a6518c0..653b407 100644
--- a/www/js/html5ks.js
+++ b/www/js/html5ks.js
@@ -1,174 +1,199 @@
-(function () {
- "use strict";
- window.html5ks = {
- data: {
- script: {}
+"use strict";
+window.html5ks = {
+ data: {
+ script: {}
+ },
+ persistent: {
+ seen_scenes: {},
+ attraction: {
+ kenji: 0,
+ sc: 0,
+ hanako: 0
},
- persistent: {
- seen_scenes: {},
- attraction: {
- kenji: 0,
- sc: 0,
- hanako: 0
+ settings: {
+ fade: 100,
+ gotit: false,
+ hdisable: false,
+ skipUnread: false,
+ skipAfterChoices: false,
+ useWebP: null,
+ fullscreen: true,
+ scaleVideo: true,
+ textSpeed: 0.5,
+ autoModeDelay: 0.2,
+ musicVolume: 1,
+ sfxVolume: 1
+ },
+ store: {}
+ },
+ state: {},
+ initElements: function () {
+ this.elements = {
+ container: document.getElementById("container"),
+ video: document.getElementById("vid"),
+ audio: {
+ music: new Audio(),
+ ambient: new Audio(),
+ sound: new Audio()
},
- hdisabled: false,
- settings: {
- // ms per character
- autospeed: 20,
- fade: 100,
- gotit: false,
- scale: true
+ who: document.getElementById("who"),
+ say: document.getElementById("say"),
+ bg: document.getElementById("bg"),
+ window: document.getElementById("window"),
+ ctc: document.getElementById("ctc")
+ };
+ this.elements.audio.music.loop = true;
+ this.elements.audio.ambient.loop = true;
+ },
+ load: function () {
+ if (localStorage.persistent) {
+ this.persistent = JSON.parse(localStorage.persistent);
+ this.loaded = true;
+ }
+ },
+ save: function () {
+ localStorage.persistent = JSON.stringify(this.persistent);
+ },
+ scale: function () {
+ if (html5ks.persistent.settings.fullscreen) {
+ var newScale = 1;
+ var height = document.documentElement.clientHeight,
+ width = document.documentElement.clientWidth;
+ if (height / width <= 0.75) { // widescreen
+ newScale = height / 600;
+ } else {
+ newScale = width / 800;
}
- },
- state: {
- auto: false
- },
- initElements: function () {
- this.elements = {
- container: document.getElementById("container"),
- video: document.getElementById("vid"),
- audio: {
- music: new Audio(),
- ambient: new Audio(),
- sound: new Audio()
- },
- who: document.getElementById("who"),
- say: document.getElementById("say"),
- bg: document.getElementById("bg"),
- window: document.getElementById("window")
- };
- this.elements.audio.music.loop = true;
- this.elements.audio.ambient.loop = true;
- },
- load: function () {
- if (localStorage.persistent) this.persistent = JSON.parse(localStorage.persistent);
- },
- save: function () {
- localStorage.persistent = JSON.stringify(this.persistent);
- },
- scale: function () {
- if (html5ks.persistent.settings.scale) {
- var newScale = 1;
- var height = document.documentElement.clientHeight,
- width = document.documentElement.clientWidth;
- if (height / width <= 0.75) { // widescreen
- newScale = height / 600;
- } else {
- newScale = width / 800;
- }
- var container = html5ks.elements.container;
- container.style.webkitTransform = "scale(" + newScale + ")";
- container.style.mozTransform = "scale(" + newScale + ")";
- container.style.transform = "scale(" + newScale + ")";
+ var container = html5ks.elements.container;
+ container.style.webkitTransform = "scale(" + newScale + ")";
+ container.style.mozTransform = "scale(" + newScale + ")";
+ container.style.transform = "scale(" + newScale + ")";
+ container.className += " scale";
- var applyScale = function (el, scale) {
- el.style.height = scale * 600 + "px";
- el.style.marginTop = "-" + scale * 300 + "px";
- el.style.width = scale * 800 + "px";
- el.style.marginLeft = "-" + scale * 400 + "px";
- };
+ var applyScale = function (el, scale) {
+ el.style.height = scale * 600 + "px";
+ el.style.marginTop = "-" + scale * 300 + "px";
+ el.style.width = scale * 800 + "px";
+ el.style.marginLeft = "-" + scale * 400 + "px";
+ el.className += " scale";
+ };
- applyScale(html5ks.elements.bg, newScale);
+ applyScale(html5ks.elements.bg, newScale);
+ if (html5ks.persistent.settings.scaleVideo) {
applyScale(html5ks.elements.video, newScale);
}
- },
- next: function () {},
- initEvents: function () {
- window.addEventListener("resize", html5ks.scale, false);
- this.elements.container.addEventListener("mouseup", function () {
- html5ks.next();
+ }
+ },
+ next: function () {},
+ initEvents: function () {
+ window.addEventListener("resize", html5ks.scale, false);
+ this.elements.container.addEventListener("mouseup", function () {
+ html5ks.next();
+ }, false);
+ var deselect = function () {
+ window.getSelection().collapse(this, 0);
+ };
+ document.body.addEventListener("mousemove", deselect, true);
+ document.body.addEventListener("mouseup", deselect, true);
+ document.body.addEventListener("keyup", deselect, true);
+ },
+ warnUnsupported: function () {
+ if (!html5ks.persistent.settings.gotit) {
+ var warn = document.getElementById("warn-container");
+ document.getElementById("gotit").addEventListener("mouseup", function () {
+ warn.style.mozAnimation = "0.5s dissolveout";
+ warn.style.webkitAnimation = "0.5s dissolveout";
+ warn.style.animation = "0.5s dissolveout";
+ warn.style.opacity = 0;
+ html5ks.persistent.settings.gotit = true;
+ html5ks.start();
}, false);
- var deselect = function () {
- window.getSelection().collapse(this, 0);
- };
- document.body.addEventListener("mousemove", deselect, true);
- document.body.addEventListener("mouseup", deselect, true);
- document.body.addEventListener("keyup", deselect, true);
- },
- warnUnsupported: function () {
- if (!html5ks.persistent.settings.gotit) {
- var warn = document.getElementById("warn-container");
- document.getElementById("gotit").addEventListener("mouseup", function () {
- warn.style.mozAnimation = "0.5s dissolveout";
- warn.style.webkitAnimation = "0.5s dissolveout";
- warn.style.animation = "0.5s dissolveout";
- warn.style.opacity = 0;
- html5ks.persistent.settings.gotit = true;
- html5ks.start();
- }, false);
- var warns = document.getElementById("warns").children;
- if (/MSIE/.test(navigator.userAgent)) {
- document.getElementById("ie").style.display = "block";
- }
- if (!(/Firefox/.test(navigator.userAgent))) {
- document.getElementById("html-svg-filter").style.display = "block";
- }
- for (var i = 0; i < warns.length; i++) {
- if (window.getComputedStyle(warns[i]).getPropertyValue("display") !== "none") {
- warn.style.visibility = "visible";
- return true;
- }
- }
+ var warns = document.getElementById("warns").children;
+ if (/MSIE/.test(navigator.userAgent)) {
+ document.getElementById("ie").style.display = "block";
}
- },
- onload: function () {
- this.initElements();
- this.load();
- this.scale();
- this.initEvents();
- if (!this.warnUnsupported()) {
- this.start();
+ if (!(/Firefox/.test(navigator.userAgent))) {
+ document.getElementById("html-svg-filter").style.display = "block";
}
- this.menu.init();
- },
- start: function () {
- this.fetch("script", "a1-monday").then(function () {
- html5ks.api.movie_cutscene("4ls").then(function () {
- html5ks.menu.mainMenu();
- });
+ for (var i = 0; i < warns.length; i++) {
+ if (window.getComputedStyle(warns[i]).getPropertyValue("display") !== "none") {
+ warn.style.visibility = "visible";
+ return true;
+ }
+ }
+ }
+ },
+ onload: function () {
+ this.initElements();
+ this.load();
+ this.scale();
+ this.initEvents();
+ if (!this.warnUnsupported()) {
+ this.start();
+ }
+ this.api.init();
+ this.menu.init();
+ },
+ winload: function () {
+ if (!this.loaded) {
+ this.persistent.settings.useWebP = Modernizr.webp;
+ }
+ if (!Modernizr.webp && this.persistent.settings.useWebP) {
+ var webpjs = document.createElement("script");
+ webpjs.src = "js/webpjs-0.0.2.min.js";
+ document.head.appendChild(webpjs);
+ }
+ },
+ start: function () {
+ this.fetch("script", "a1-monday").then(function () {
+ html5ks.api.movie_cutscene("4ls").then(function () {
+ html5ks.menu.mainMenu();
});
- },
- fetch: function (type, name) {
- var deferred = when.defer();
- var xhr = new XMLHttpRequest();
- switch (type) {
- case "script":
- var script = html5ks.data.script;
- if (script[name]) {
- deferred.resolve();
- } else {
- xhr.open("GET", "scripts/script-" + name + ".json");
- xhr.onreadystatechange = function () {
- script[name] = true;
- if (xhr.readyState === 4) {
- var resp = JSON.parse(xhr.responseText);
- for (var label in resp) {
- script[label] = resp[label];
- }
- deferred.resolve();
- }
- };
- xhr.send();
- }
- break;
- case "imachine":
- xhr.open("GET", "scripts/imachine.json");
+ });
+ },
+ fetch: function (type, name) {
+ var deferred = when.defer();
+ var xhr = new XMLHttpRequest();
+ switch (type) {
+ case "script":
+ var script = html5ks.data.script;
+ if (script[name]) {
+ deferred.resolve();
+ } else {
+ xhr.open("GET", "scripts/script-" + name + ".json");
xhr.onreadystatechange = function () {
+ script[name] = true;
if (xhr.readyState === 4) {
- html5ks.data.imachine = JSON.parse(xhr.responseText);
+ var resp = JSON.parse(xhr.responseText);
+ for (var label in resp) {
+ script[label] = resp[label];
+ }
deferred.resolve();
}
};
xhr.send();
- break;
- default:
- throw new Error("fetchtype " + type + " not implemented");
- }
- return deferred.promise;
+ }
+ break;
+ case "imachine":
+ xhr.open("GET", "scripts/imachine.json");
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4) {
+ html5ks.data.imachine = JSON.parse(xhr.responseText);
+ deferred.resolve();
+ }
+ };
+ xhr.send();
+ break;
+ default:
+ throw new Error("fetchtype " + type + " not implemented");
}
- };
- document.addEventListener("DOMContentLoaded", function () {
- html5ks.onload();
- }, false);
-}());
+ return deferred.promise;
+ }
+};
+document.addEventListener("DOMContentLoaded", function () {
+ html5ks.onload();
+}, false);
+window.addEventListener("onload", function () {
+ html5ks.winload();
+}, false);
diff --git a/www/js/menu.js b/www/js/menu.js
index 589ae41..a57f9a0 100644
--- a/www/js/menu.js
+++ b/www/js/menu.js
@@ -14,15 +14,16 @@
activeDialog: null,
dialog: function (name) {
- this.activeDialog = html5ks.elements.dialog[name];
+ this.activeDialog = this.elements.dialog[name];
this.activeDialog.style.display = "block";
- html5ks.elements.dialogs.style.display = "block";
+ this.elements.dialogs.style.display = "block";
},
initElements: function () {
this.elements = {
dialogs: document.getElementById("dialogs"),
dialog: {
+ options: document.getElementById("options"),
return: document.getElementById("return")
},
mainMenu: document.getElementById("main-menu"),
@@ -33,8 +34,34 @@
};
},
+ initOptions: function () {
+ var options = document.getElementsByClassName("option"),
+ values = html5ks.persistent.settings;
+
+ for (var i = options.length - 1; i >= 0; i--) {
+ var option = options[i];
+ switch (option.type) {
+ case "checkbox":
+ option.checked = values[option.id];
+ option.addEventListener("change", function () {
+ values[this.id] = this.checked;
+ }, false);
+ break;
+ case "range":
+ option.value = values[option.id];
+ option.addEventListener("change", function () {
+ values[this.id] = this.value;
+ }, false);
+ break;
+ default:
+ console.error("unknown option type %s", option.type);
+ }
+ }
+ },
+
init: function () {
this.initElements();
+ this.initOptions();
this.elements.main.start.addEventListener("click", function () {
if (this._imachine_loaded) {
this.elements.mainMenu.style.display = "none";
@@ -46,7 +73,7 @@
}, false);
this.elements.dialog.return.addEventListener("click", function (e) {
html5ks.menu.activeDialog.style.display = "none";
- html5ks.elements.dialogs.style.display = "none";
+ html5ks.menu.elements.dialogs.style.display = "none";
}, false);
html5ks.fetch("imachine").then(function () {
var start = this.elements.main.start;