|
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
|
|
<!-- saved from url=(0055)https://floooh.github.io/sokol-html5/triangle-sapp.html -->
|
|
|
|
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
|
|
|
|
|
|
<title>AI RPG</title>
|
|
|
|
<style type="text/css">
|
|
|
|
body {
|
|
|
|
margin: 0;
|
|
|
|
background-color: black;
|
|
|
|
}
|
|
|
|
.game-title {
|
|
|
|
pointer-events: none;
|
|
|
|
position: absolute;
|
|
|
|
bottom: 10px;
|
|
|
|
margin-top: 0px;
|
|
|
|
padding-left: 10px;
|
|
|
|
color: white;
|
|
|
|
text-decoration: none;
|
|
|
|
z-index: 1;
|
|
|
|
text-align: left;
|
|
|
|
font-family: "Arial Black", Gadget, sans-serif;
|
|
|
|
font-size: 30px;
|
|
|
|
}
|
|
|
|
.game-menu-item {
|
|
|
|
pointer-events: auto;
|
|
|
|
font-size: 18px;
|
|
|
|
padding-left: 10px;
|
|
|
|
font-family: Arial, Helvetica, sans-serif;
|
|
|
|
}
|
|
|
|
.game-menu-link {
|
|
|
|
text-decoration: none;
|
|
|
|
color: white;
|
|
|
|
}
|
|
|
|
.game {
|
|
|
|
position: absolute;
|
|
|
|
top: 0px;
|
|
|
|
left: 0px;
|
|
|
|
margin: 0px;
|
|
|
|
border: 0;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
overflow: hidden;
|
|
|
|
display: block;
|
|
|
|
image-rendering: optimizeSpeed;
|
|
|
|
image-rendering: -moz-crisp-edges;
|
|
|
|
image-rendering: -o-crisp-edges;
|
|
|
|
image-rendering: -webkit-optimize-contrast;
|
|
|
|
image-rendering: optimize-contrast;
|
|
|
|
image-rendering: crisp-edges;
|
|
|
|
image-rendering: pixelated;
|
|
|
|
-ms-interpolation-mode: nearest-neighbor;
|
|
|
|
}
|
|
|
|
.inputdiv {
|
|
|
|
position: absolute;
|
|
|
|
top: 0px;
|
|
|
|
left: 0px;
|
|
|
|
margin: 0px;
|
|
|
|
border: 0;
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
overflow: hidden;
|
|
|
|
display: none; /* set to flex by javascript */
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
z-index: 10;
|
|
|
|
background: #00000090;
|
|
|
|
}
|
|
|
|
#inputtext {
|
|
|
|
position: absolute;
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
|
|
|
|
background: none;
|
|
|
|
width: 90%;
|
|
|
|
height: 50%;
|
|
|
|
margin-left: 5%;
|
|
|
|
margin-right: 5%;
|
|
|
|
border-top-style: hidden;
|
|
|
|
border-right-style: hidden;
|
|
|
|
border-left-style: hidden;
|
|
|
|
border-bottom-style: hidden;
|
|
|
|
transform: translateY(100%);
|
|
|
|
text-align: center;
|
|
|
|
font-size: 2em;
|
|
|
|
font-family: Arial;
|
|
|
|
color: white;
|
|
|
|
}
|
|
|
|
|
|
|
|
#inputtext:focus {
|
|
|
|
outline: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
#inputbutton {
|
|
|
|
bottom: 0;
|
|
|
|
margin-bottom: 10%;
|
|
|
|
position: absolute;
|
|
|
|
font-family: Arial;
|
|
|
|
font-size: 3em;
|
|
|
|
}
|
|
|
|
|
|
|
|
</style>
|
|
|
|
<link id="sokol-app-favicon" rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAZdJREFUOE9VUzFSw0AMlGihggekwhV0eQGZ8AQggQ4chlR5CjSeAUwHOHkCZPALoEuVVHkAdCnxMVpJd8YzHt/5pNXuSsdkDxNRkHfSC8REIZB88ASSXxrBdzU+tiVmBHs6UQMAiwgK6kCy4NsPACBPcfQ4VPtSSLdSfbjEmg0kVBkKMQ7lfIXKAoTnt8okPVbjwUqCJR//mtdMpaEa09ZwCZyopfk5g5Doye7UTz0JuUovfti0EIXvAbS7ebw3BaFIwaQAAwAqxzwAUTBYrE8AokG2AIpmHnZmzkG9aLHGcrE+1VoC14a3Nh90ZsKLOSTP/2OYc9pZxReq5Vce5UnqVfdJDlIXEklzOhkFpeXnJQQ7aN4tZcCsi0w0ehtrgMm/7xemAJ2n6/mNdtBseegXykCtJsrfx0ZC3RWA9hCO5uM0r4Ho8bjwgYwWIODoZYPZj8326UCpQPXFjsnAPEvtdA9k2XvegCV6ZZeq3av6fBvUvYZKsBbZiQI4tG0kQzW6kzrE1qfW/cWk+i1w14WuGxgvBOD+AP0MuCLRb/uuAAAAAElFTkSuQmCC"></head>
|
|
|
|
<body style="background:black">
|
|
|
|
<div id="inputdiv" class="inputdiv">
|
|
|
|
<textarea onkeyup='on_textarea_key(event);' id="inputtext">
|
|
|
|
</textarea>
|
|
|
|
<button id="inputbutton" onclick="end_dialog()"> Submit </button>
|
|
|
|
</div>
|
|
|
|
<canvas class="game" id="canvas" oncontextmenu="event.preventDefault()" width="1504" height="864"></canvas>
|
|
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
|
|
var Module = {
|
|
|
|
preRun: [],
|
|
|
|
postRun: [],
|
|
|
|
print: (function() {
|
|
|
|
return function(text) {
|
|
|
|
text = Array.prototype.slice.call(arguments).join(' ');
|
|
|
|
console.log(text);
|
|
|
|
};
|
|
|
|
})(),
|
|
|
|
printErr: function(text) {
|
|
|
|
text = Array.prototype.slice.call(arguments).join(' ');
|
|
|
|
console.error(text);
|
|
|
|
},
|
|
|
|
canvas: (function() {
|
|
|
|
var canvas = document.getElementById('canvas');
|
|
|
|
canvas.addEventListener("webglcontextlost", function(e) { alert('FIXME: WebGL context lost, please reload the page'); e.preventDefault(); }, false);
|
|
|
|
return canvas;
|
|
|
|
})(),
|
|
|
|
setStatus: function(text) { },
|
|
|
|
monitorRunDependencies: function(left) { },
|
|
|
|
};
|
|
|
|
window.onerror = function(event) {
|
|
|
|
console.log("onerror: " + event.message);
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
|
|
|
|
|
|
function start_dialog() {
|
|
|
|
document.getElementById("inputtext").value = "";
|
|
|
|
setTimeout(function(){document.getElementById("inputtext").focus();},200); // for some reason focus doesn't work immediately here
|
|
|
|
document.getElementById("inputdiv").style.display = "flex";
|
|
|
|
}
|
|
|
|
function end_dialog() {
|
|
|
|
document.getElementById("inputdiv").style.display = "none";
|
|
|
|
Module.ccall('end_text_input', 'void', ['string'], [document.getElementById("inputtext").value]);
|
|
|
|
}
|
|
|
|
|
|
|
|
function on_textarea_key(event) {
|
|
|
|
let final_textarea_string = "";
|
|
|
|
let cur_textarea_string = document.getElementById("inputtext").value;
|
|
|
|
for(let i = 0; i < Math.min(cur_textarea_string.length, 250); i++)
|
|
|
|
{
|
|
|
|
let cur = cur_textarea_string[i];
|
|
|
|
if(cur === "\n") continue;
|
|
|
|
if(cur.charCodeAt(0) >= 255) continue; // non ascii gtfo
|
|
|
|
final_textarea_string += cur_textarea_string[i];
|
|
|
|
}
|
|
|
|
document.getElementById("inputtext").value = final_textarea_string;
|
|
|
|
if(event.key === "Enter") end_dialog();
|
|
|
|
if(event.key === "Escape")
|
|
|
|
{
|
|
|
|
document.getElementById("inputtext").value = "";
|
|
|
|
end_dialog();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const max_retries = 5;
|
|
|
|
let cur_id = 1; // zero is not a valid id, the zero value means no async request currently active
|
|
|
|
let generation_requests = []; // array of dictionaries with structure:
|
|
|
|
/*
|
|
|
|
{ id: number,
|
|
|
|
request: XMLHTTPRequest,
|
|
|
|
request_info: { url: string, body: string }
|
|
|
|
retries_remaining: number, // on failure, retries over and over until out of retries
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
function resend_request(r) {
|
|
|
|
r.request.open("POST", r.request_info.url, true);
|
|
|
|
r.request.send(r.request_info.body);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns an integer, a "handle" into the generation request. Takes in the string prompt, and api URL
|
|
|
|
// the api url must start with `http://` or https.
|
|
|
|
function make_generation_request(p, api) {
|
|
|
|
cur_id += 1;
|
|
|
|
let to_push = {
|
|
|
|
"id": cur_id,
|
|
|
|
"request": new XMLHttpRequest(),
|
|
|
|
"retries_remaining": 5,
|
|
|
|
"request_info": {"url": api, "body": p}
|
|
|
|
}
|
|
|
|
console.log("Making generation request with id " + to_push.id);
|
|
|
|
generation_requests.push(to_push)
|
|
|
|
resend_request(to_push)
|
|
|
|
return cur_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
// returns 0 if not done yet, 1 if succeeded, 2 if failed after too many retries (i.e server down, or no internet)
|
|
|
|
// -1 if it doesn't exist
|
|
|
|
function get_generation_request_status(id) {
|
|
|
|
for(let i = 0; i < generation_requests.length; i++) {
|
|
|
|
if(generation_requests[i].id == id) {
|
|
|
|
let http_status = generation_requests[i].request.status;
|
|
|
|
if(http_status == 200) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if(http_status == 0) { // not done yet
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else { // errored
|
|
|
|
if(generation_requests[i].retries_remaining > 0) {
|
|
|
|
generation_requests[i].retries_remaining -= 1;
|
|
|
|
resend_request(generation_requests[i]);
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return 2; // too many retries, failed
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
function done_with_generation_request(id) {
|
|
|
|
console.log("Removing request with id " + id);
|
|
|
|
let new_generation_requests = [];
|
|
|
|
for(let i = 0; i < generation_requests.length; i++) {
|
|
|
|
if(generation_requests[i].id == id)
|
|
|
|
{
|
|
|
|
} else {
|
|
|
|
new_generation_requests.push(generation_requests[i])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
generation_requests = new_generation_requests;
|
|
|
|
}
|
|
|
|
|
|
|
|
// doesn't fill string if not done yet, or the id doesn't exist
|
|
|
|
function get_generation_request_content(id) {
|
|
|
|
let to_return = "";
|
|
|
|
for(let i = 0; i < generation_requests.length; i++) {
|
|
|
|
if(generation_requests[i].id == id) {
|
|
|
|
to_return = generation_requests[i].request.responseText;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return to_return;;
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
{{{ SCRIPT }}}
|
|
|
|
|
|
|
|
</body></html>
|
|
|
|
|