lots of stuff
This commit is contained in:
parent
0cb4f3af8d
commit
03588c4c55
|
@ -13,6 +13,8 @@ crate-type = ["cdylib"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
"base64" = "^0.12.3"
|
"base64" = "^0.12.3"
|
||||||
"bitsy-parser" = "^0.72.3"
|
"bitsy-parser" = "^0.72.3"
|
||||||
|
"dither" = "1.3.9"
|
||||||
"image" = "^0.23.7"
|
"image" = "^0.23.7"
|
||||||
|
"json" = "^0.12.4"
|
||||||
"lazy_static" = "^1.4.0"
|
"lazy_static" = "^1.4.0"
|
||||||
"wasm-bindgen" = "=0.2.64" # newer versions are bugged...
|
"wasm-bindgen" = "=0.2.64" # newer versions are bugged...
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
# todo
|
||||||
|
|
||||||
|
* preview
|
||||||
|
* dithering
|
||||||
|
* palette selection
|
||||||
|
* palette dropdown
|
||||||
|
* unit test
|
||||||
|
* if uploaded image is exactly 128×128, *don't* crop
|
|
@ -4,4 +4,4 @@
|
||||||
rm -rf dist
|
rm -rf dist
|
||||||
mkdir dist
|
mkdir dist
|
||||||
cp -r README.md LICENSE index.html script.js background.png pkg includes dist
|
cp -r README.md LICENSE index.html script.js background.png pkg includes dist
|
||||||
butler push dist ruin/image-to-bitsy:html
|
# butler push dist ruin/pixsy:html
|
||||||
|
|
|
@ -58,7 +58,6 @@ input {
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
max-height: 12em;
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
@ -73,6 +72,10 @@ label {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
height: 15em;
|
height: 15em;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
@ -94,6 +97,12 @@ textarea {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.half {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
.image-container {
|
.image-container {
|
||||||
height: 46vh;
|
height: 46vh;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
@ -114,3 +123,10 @@ textarea {
|
||||||
#crop canvas {
|
#crop canvas {
|
||||||
height: 32vh;
|
height: 32vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#preview {
|
||||||
|
width: 256px;
|
||||||
|
height: 256px;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
image-rendering: crisp-edges;
|
||||||
|
}
|
||||||
|
|
43
index.pug
43
index.pug
|
@ -24,34 +24,63 @@ html(lang="en-gb")
|
||||||
button.normal.pagination.next#load load an existing bitsy game
|
button.normal.pagination.next#load load an existing bitsy game
|
||||||
.page.game-data
|
.page.game-data
|
||||||
h2 game data
|
h2 game data
|
||||||
|
|
||||||
input#game(type="file" autocomplete="off")
|
input#game(type="file" autocomplete="off")
|
||||||
br
|
br
|
||||||
|
|
||||||
textarea#game-data(
|
textarea#game-data(
|
||||||
placeholder="Paste your game data here or use the file chooser button above"
|
placeholder="Paste your game data here or use the file chooser button above"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
)
|
)
|
||||||
|
|
||||||
button.pagination.prev previous
|
button.pagination.prev previous
|
||||||
button.pagination.next#game-data-next(disabled=true) next
|
button.pagination.next#game-data-next(disabled=true) next
|
||||||
.page.image
|
.page.image
|
||||||
h2 image
|
h2 image
|
||||||
|
|
||||||
.image-container
|
.image-container
|
||||||
input#image(type="file" accept="image/*")
|
input#image(type="file" accept="image/*")
|
||||||
#crop
|
#crop
|
||||||
|
|
||||||
button.pagination.prev previous
|
button.pagination.prev previous
|
||||||
button.pagination.next next
|
button.pagination.next#image-next(disabled=true) next
|
||||||
.page.extras
|
.page.room
|
||||||
h2 tiles
|
h2 room
|
||||||
label
|
|
||||||
| tile name (optional)
|
table
|
||||||
input#prefix(type="text" placeholder="e.g. 'forest'" autocomplete="off")
|
tbody
|
||||||
|
tr
|
||||||
|
td(style="width: 60%")
|
||||||
|
img#preview(alt="preview")
|
||||||
|
br
|
||||||
|
|
||||||
|
label
|
||||||
|
| brightness
|
||||||
|
input#brightness(type="range" min=-64 max=64 value=0)
|
||||||
|
td
|
||||||
|
label
|
||||||
|
| palette
|
||||||
|
select#palette
|
||||||
|
|
||||||
|
label
|
||||||
|
input#dither(type="checkbox")
|
||||||
|
| dither
|
||||||
|
br
|
||||||
|
|
||||||
|
label
|
||||||
|
| name (optional)
|
||||||
|
input#room-name(type="text" placeholder="e.g. 'bedroom'" autocomplete="off")
|
||||||
|
|
||||||
button.pagination.prev#back-to-image previous
|
button.pagination.prev#back-to-image previous
|
||||||
button.pagination.next#import next
|
button.pagination.next#room-next next
|
||||||
.page.download
|
.page.download
|
||||||
h2 download
|
h2 download
|
||||||
|
|
||||||
textarea#output(autocomplete="off")
|
textarea#output(autocomplete="off")
|
||||||
br
|
br
|
||||||
|
|
||||||
button#download download
|
button#download download
|
||||||
|
|
||||||
button.pagination.prev#add add another image
|
button.pagination.prev#add add another image
|
||||||
button.pagination.start#reset start again
|
button.pagination.start#reset start again
|
||||||
script(type="module")
|
script(type="module")
|
||||||
|
|
56
script.js
56
script.js
|
@ -1,14 +1,17 @@
|
||||||
import init, {
|
import init, {
|
||||||
add_room,
|
add_room,
|
||||||
|
get_palettes,
|
||||||
|
get_preview,
|
||||||
load_image,
|
load_image,
|
||||||
load_game,
|
load_game,
|
||||||
load_default_game,
|
load_default_game,
|
||||||
output,
|
output,
|
||||||
|
set_dither,
|
||||||
set_room_name,
|
set_room_name,
|
||||||
} from './pkg/pixsy.js';
|
} from './pkg/pixsy.js';
|
||||||
|
|
||||||
if (typeof WebAssembly !== "object") {
|
if (typeof WebAssembly !== "object") {
|
||||||
document.getElementById("start").innerText = "Sorry - your browser does not support WebAssembly";
|
window.location = "./old/"
|
||||||
}
|
}
|
||||||
|
|
||||||
// stolen from https://ourcodeworld.com/articles/read/189/how-to-create-a-file-and-generate-a-download-with-javascript-in-the-browser-without-a-server
|
// stolen from https://ourcodeworld.com/articles/read/189/how-to-create-a-file-and-generate-a-download-with-javascript-in-the-browser-without-a-server
|
||||||
|
@ -61,10 +64,14 @@ async function run() {
|
||||||
const buttonBackToImage = el("back-to-image");
|
const buttonBackToImage = el("back-to-image");
|
||||||
const buttonDownload = el("download");
|
const buttonDownload = el("download");
|
||||||
const buttonGameDataProceed = el("game-data-next");
|
const buttonGameDataProceed = el("game-data-next");
|
||||||
const buttonImportGame = el("import");
|
const buttonImageProceed = el("image-next");
|
||||||
|
const buttonRoomProceed = el("room-next");
|
||||||
const buttonLoadGame = el("load");
|
const buttonLoadGame = el("load");
|
||||||
const buttonNewGame = el("new");
|
const buttonNewGame = el("new");
|
||||||
const buttonReset = el("reset");
|
const buttonReset = el("reset");
|
||||||
|
const checkboxDither = el("dither");
|
||||||
|
const inputRoomName = el("room-name");
|
||||||
|
const selectPalette = el("palette");
|
||||||
const textareaGameDataInput = el("game-data");
|
const textareaGameDataInput = el("game-data");
|
||||||
const textareaGameDataOutput = el("output");
|
const textareaGameDataOutput = el("output");
|
||||||
|
|
||||||
|
@ -110,9 +117,25 @@ async function run() {
|
||||||
}, "text");
|
}, "text");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function setPaletteDropdown() {
|
||||||
|
let palettes = JSON.parse(get_palettes());
|
||||||
|
|
||||||
|
selectPalette.innerHTML = "";
|
||||||
|
|
||||||
|
for (let palette of palettes) {
|
||||||
|
let option = document.createElement("option");
|
||||||
|
|
||||||
|
option.value = palette.id;
|
||||||
|
option.innerText = palette.name;
|
||||||
|
|
||||||
|
selectPalette.appendChild(option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkGameData() {
|
function checkGameData() {
|
||||||
if (textareaGameDataInput.value.length > 0) {
|
if (textareaGameDataInput.value.length > 0) {
|
||||||
buttonGameDataProceed.removeAttribute("disabled");
|
buttonGameDataProceed.removeAttribute("disabled");
|
||||||
|
setPaletteDropdown();
|
||||||
} else {
|
} else {
|
||||||
buttonGameDataProceed.setAttribute("disabled", "disabled");
|
buttonGameDataProceed.setAttribute("disabled", "disabled");
|
||||||
}
|
}
|
||||||
|
@ -127,19 +150,40 @@ async function run() {
|
||||||
if ( ! cropperRendered) {
|
if ( ! cropperRendered) {
|
||||||
cropper.render("#crop");
|
cropper.render("#crop");
|
||||||
cropperRendered = true;
|
cropperRendered = true;
|
||||||
|
buttonImageProceed.removeAttribute("disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
cropper.loadImage(e.target.result);
|
cropper.loadImage(e.target.result);
|
||||||
}, "image");
|
}, "image");
|
||||||
});
|
});
|
||||||
|
|
||||||
function addTiles() {
|
function loadPreview() {
|
||||||
console.log(add_tiles());
|
el("preview").setAttribute("src", get_preview());
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleImage() {
|
||||||
|
console.log(load_image(cropper.getCroppedImage()));
|
||||||
|
loadPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonImageProceed.addEventListener("click", handleImage);
|
||||||
|
buttonImageProceed.addEventListener("touchend", handleImage);
|
||||||
|
|
||||||
|
checkboxDither.addEventListener("change", () => {
|
||||||
|
set_dither(checkboxDither.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
inputRoomName.addEventListener("change", () => {
|
||||||
|
set_room_name(inputRoomName.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
function addRoom() {
|
||||||
|
console.log(add_room());
|
||||||
textareaGameDataOutput.value = output();
|
textareaGameDataOutput.value = output();
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonImportGame.addEventListener("click", addTiles);
|
buttonRoomProceed.addEventListener("click", addRoom);
|
||||||
buttonImportGame.addEventListener("touchend", addTiles);
|
buttonRoomProceed.addEventListener("touchend", addRoom);
|
||||||
|
|
||||||
function handleDownload() {
|
function handleDownload() {
|
||||||
download("output.bitsy", textareaGameDataOutput.value);
|
download("output.bitsy", textareaGameDataOutput.value);
|
||||||
|
|
106
src/lib.rs
106
src/lib.rs
|
@ -5,6 +5,7 @@ use image::{GenericImageView, Pixel, DynamicImage};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
use image::imageops::dither;
|
||||||
|
|
||||||
const SD: u32 = 8;
|
const SD: u32 = 8;
|
||||||
|
|
||||||
|
@ -13,6 +14,7 @@ struct State {
|
||||||
image: Option<DynamicImage>,
|
image: Option<DynamicImage>,
|
||||||
room_name: Option<String>,
|
room_name: Option<String>,
|
||||||
palette: Option<String>,
|
palette: Option<String>,
|
||||||
|
dither: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
@ -22,6 +24,7 @@ lazy_static! {
|
||||||
image: None,
|
image: None,
|
||||||
room_name: None,
|
room_name: None,
|
||||||
palette: None,
|
palette: None,
|
||||||
|
dither: true,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +41,7 @@ fn tile_name(prefix: &Option<String>, index: &u32) -> Option<String> {
|
||||||
pub fn load_default_game() {
|
pub fn load_default_game() {
|
||||||
let mut state = STATE.lock().unwrap();
|
let mut state = STATE.lock().unwrap();
|
||||||
state.game = Some(bitsy_parser::mock::game_default());
|
state.game = Some(bitsy_parser::mock::game_default());
|
||||||
|
state.palette = Some(bitsy_parser::mock::game_default().palette_ids()[0].clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
@ -47,11 +51,14 @@ pub fn load_game(game_data: String) -> String {
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(game) => {
|
Ok(game) => {
|
||||||
state.game = Some(game);
|
let palette_id = game.palette_ids()[0].clone();
|
||||||
|
state.game = Some(game);
|
||||||
|
state.palette = Some(palette_id);
|
||||||
"".to_string()
|
"".to_string()
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
state.game = None;
|
state.game = None;
|
||||||
|
state.palette = None;
|
||||||
format!("{}", result.err().unwrap())
|
format!("{}", result.err().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +91,22 @@ pub fn load_image(image_base64: String) -> String {
|
||||||
}.to_string()
|
}.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn set_dither(dither: bool) {
|
||||||
|
let mut state = STATE.lock().unwrap();
|
||||||
|
state.dither = dither;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn set_palette(palette_id: String) {
|
||||||
|
let mut state = STATE.lock().unwrap();
|
||||||
|
|
||||||
|
match palette_id.is_empty() {
|
||||||
|
true => { state.palette = None },
|
||||||
|
false => { state.palette = Some(palette_id) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn set_room_name(room_name: String) {
|
pub fn set_room_name(room_name: String) {
|
||||||
let mut state = STATE.lock().unwrap();
|
let mut state = STATE.lock().unwrap();
|
||||||
|
@ -95,12 +118,52 @@ pub fn set_room_name(room_name: String) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn set_palette(palette_id: String) {
|
pub fn get_palettes() -> String {
|
||||||
let mut state = STATE.lock().unwrap();
|
let state = STATE.lock().unwrap();
|
||||||
|
|
||||||
match palette_id.is_empty() {
|
let mut palette_objects = json::JsonValue::new_array();
|
||||||
true => { state.palette = None },
|
|
||||||
false => { state.palette = Some(palette_id) },
|
for palette in &state.game.as_ref().unwrap().palettes {
|
||||||
|
let mut object = json::JsonValue::new_object();
|
||||||
|
|
||||||
|
object.insert("id", palette.id.clone()).unwrap();
|
||||||
|
|
||||||
|
object.insert(
|
||||||
|
"name",
|
||||||
|
palette.name.clone().unwrap_or(
|
||||||
|
format!("Palette {}", palette.id))
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
palette_objects.push(object).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
json::stringify(palette_objects)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn image_to_base64(image: &DynamicImage) -> String {
|
||||||
|
let mut bytes: Vec<u8> = Vec::new();
|
||||||
|
image.write_to(&mut bytes, image::ImageOutputFormat::Png).unwrap();
|
||||||
|
format!("data:image/png;base64,{}", base64::encode(&bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_preview(image: &DynamicImage) -> DynamicImage {
|
||||||
|
let image = image.clone();
|
||||||
|
let image = image.grayscale();
|
||||||
|
|
||||||
|
// todo dither
|
||||||
|
|
||||||
|
// todo convert to palette colours
|
||||||
|
|
||||||
|
image
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn get_preview() -> String {
|
||||||
|
let state = STATE.lock().unwrap();
|
||||||
|
|
||||||
|
match &state.image.is_some() {
|
||||||
|
true => image_to_base64(&render_preview(state.image.as_ref().unwrap())),
|
||||||
|
false => "".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,13 +237,38 @@ pub fn output() -> String {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{add_tiles, load_image, load_default_game, output};
|
use crate::{add_room, load_image, load_default_game, output, get_preview};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn image_to_base64() {
|
||||||
|
let image = image::load_from_memory(include_bytes!("test-resources/test.png")).unwrap();
|
||||||
|
let output = crate::image_to_base64(&image);
|
||||||
|
let expected = include_str!("test-resources/test.png.base64").trim();
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_palettes() {
|
||||||
|
load_default_game();
|
||||||
|
let output = crate::get_palettes();
|
||||||
|
let expected = "[{\"id\":\"0\",\"name\":\"blueprint\"}]";
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn render_preview() {
|
||||||
|
load_default_game();
|
||||||
|
load_image(include_str!("test-resources/colour_input.png.base64").trim().to_string());
|
||||||
|
let output = get_preview();
|
||||||
|
let expected = include_str!("test-resources/colour_input.png.base64.greyscale").trim();
|
||||||
|
assert_eq!(output, expected);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn example() {
|
fn example() {
|
||||||
load_default_game();
|
load_default_game();
|
||||||
load_image(include_str!("test-resources/test.png.base64").to_string());
|
load_image(include_str!("test-resources/test.png.base64").to_string());
|
||||||
add_tiles();
|
add_room();
|
||||||
|
|
||||||
assert_eq!(output(), include_str!("test-resources/expected.bitsy"));
|
assert_eq!(output(), include_str!("test-resources/expected.bitsy"));
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,136 @@
|
||||||
|
Write your game's title here
|
||||||
|
|
||||||
|
# BITSY VERSION 7.2
|
||||||
|
|
||||||
|
! ROOM_FORMAT 1
|
||||||
|
|
||||||
|
PAL 0
|
||||||
|
NAME blueprint
|
||||||
|
0,82,204
|
||||||
|
128,159,255
|
||||||
|
255,255,255
|
||||||
|
|
||||||
|
ROOM 0
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
0,a,a,a,a,a,a,a,a,a,a,a,a,a,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,0,0,0,0,0,0,0,0,0,0,0,0,a,0
|
||||||
|
0,a,a,a,a,a,a,a,a,a,a,a,a,a,a,0
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
NAME example room
|
||||||
|
PAL 0
|
||||||
|
|
||||||
|
TIL a
|
||||||
|
11111111
|
||||||
|
10000001
|
||||||
|
10000001
|
||||||
|
10011001
|
||||||
|
10011001
|
||||||
|
10000001
|
||||||
|
10000001
|
||||||
|
11111111
|
||||||
|
NAME block
|
||||||
|
|
||||||
|
TIL 2
|
||||||
|
00011000
|
||||||
|
00111000
|
||||||
|
00011000
|
||||||
|
00011000
|
||||||
|
00011000
|
||||||
|
00011000
|
||||||
|
00011000
|
||||||
|
00111100
|
||||||
|
|
||||||
|
TIL 3
|
||||||
|
00111100
|
||||||
|
01100110
|
||||||
|
01100110
|
||||||
|
00001100
|
||||||
|
00011000
|
||||||
|
00110000
|
||||||
|
01100000
|
||||||
|
01111110
|
||||||
|
|
||||||
|
TIL 4
|
||||||
|
00111100
|
||||||
|
01100110
|
||||||
|
01100110
|
||||||
|
00001100
|
||||||
|
00001100
|
||||||
|
01100110
|
||||||
|
01100110
|
||||||
|
00111100
|
||||||
|
|
||||||
|
SPR A
|
||||||
|
00011000
|
||||||
|
00011000
|
||||||
|
00011000
|
||||||
|
00111100
|
||||||
|
01111110
|
||||||
|
10111101
|
||||||
|
00100100
|
||||||
|
00100100
|
||||||
|
POS 0 4,4
|
||||||
|
|
||||||
|
SPR a
|
||||||
|
00000000
|
||||||
|
00000000
|
||||||
|
01010001
|
||||||
|
01110001
|
||||||
|
01110010
|
||||||
|
01111100
|
||||||
|
00111100
|
||||||
|
00100100
|
||||||
|
NAME cat
|
||||||
|
DLG 0
|
||||||
|
POS 0 8,12
|
||||||
|
|
||||||
|
ITM 0
|
||||||
|
00000000
|
||||||
|
00000000
|
||||||
|
00000000
|
||||||
|
00111100
|
||||||
|
01100100
|
||||||
|
00100100
|
||||||
|
00011000
|
||||||
|
00000000
|
||||||
|
NAME tea
|
||||||
|
DLG 1
|
||||||
|
|
||||||
|
ITM 1
|
||||||
|
00000000
|
||||||
|
00111100
|
||||||
|
00100100
|
||||||
|
00111100
|
||||||
|
00010000
|
||||||
|
00011000
|
||||||
|
00010000
|
||||||
|
00011000
|
||||||
|
NAME key
|
||||||
|
DLG 2
|
||||||
|
|
||||||
|
DLG 0
|
||||||
|
I'm a cat
|
||||||
|
NAME cat dialog
|
||||||
|
|
||||||
|
DLG 1
|
||||||
|
You found a nice warm cup of tea
|
||||||
|
NAME tea dialog
|
||||||
|
|
||||||
|
DLG 2
|
||||||
|
A key! {wvy}What does it open?{wvy}
|
||||||
|
NAME key dialog
|
||||||
|
|
||||||
|
VAR a
|
||||||
|
42
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 234 B |
|
@ -0,0 +1 @@
|
||||||
|
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAQCAYAAACm53kpAAAAvElEQVR4nO2QQQrDMBAD6/8/upVSBMqClab2IWAP2M1qtgmovcFrgNYa7i96lWdO8nKi7oz6HkcBvWUo3FgKXo7PQpmTvJzy2XNiWgGEM/HM6fmaz54TpwLwiBvhjVnPhDPxzLny5Gpn1FceVcCoJ7/sOKcCKlC4sRS8O87EMyf55Ejy1dU58YgCerm46+ucOArA79/oI/U1ykXy1QntXHlSd9wluHX+52LsAnB2ATjLsgvA2QXgLMvyBXwAjqzoAQg4VfAAAAAASUVORK5CYII=
|
Loading…
Reference in New Issue