Compare commits

..

No commits in common. "6a58e8c003585ac4d48732e6d0b4d0a644544b86" and "31d7ff52ca8f3af232443cb93911f26fccd927e8" have entirely different histories.

4 changed files with 30 additions and 80 deletions

View File

@ -11,9 +11,9 @@ repository = "https://tinybird.dev/max/image-to-bitsy"
crate-type = ["cdylib"]
[dependencies]
base64 = "^0.12.3"
bitsy-parser = "^0.72.5"
image = "^0.23.7"
json = "^0.12.4"
lazy_static = "^1.4.0"
wasm-bindgen = "=0.2.64" # newer versions are bugged...
"base64" = "^0.12.3"
"bitsy-parser" = "^0.72.4"
"image" = "^0.23.7"
"json" = "^0.12.4"
"lazy_static" = "^1.4.0"
"wasm-bindgen" = "=0.2.64" # newer versions are bugged...

View File

@ -62,12 +62,6 @@ html(lang="en-gb")
| palette
select#palette
#new-palette(style="display: none;")
.half
input#colour-background(type="color" value="#2f4ac9")
.half
input#colour-foreground(type="color" value="#8798fe")
label
input#dither(type="checkbox" checked=true)
| dither

View File

@ -72,10 +72,7 @@ async function run() {
const buttonNewGame = el("new");
const buttonReset = el("reset");
const checkboxDither = el("dither");
const divNewPalette = el("new-palette");
const inputBrightness = el("brightness");
const inputColourBackground = el("colour-background");
const inputColourForeground = el("colour-foreground");
const inputRoomName = el("room-name");
const selectPalette = el("palette");
const textareaGameDataInput = el("game-data");
@ -129,11 +126,6 @@ async function run() {
selectPalette.innerHTML = "";
palettes.push({
id: "NEW_PALETTE",
name: "new palette"
});
for (let palette of palettes) {
let option = document.createElement("option");
@ -182,25 +174,10 @@ async function run() {
buttonImageProceed.addEventListener("touchend", handleImage);
selectPalette.addEventListener("change", () => {
set_palette(selectPalette.value, inputColourBackground.value, inputColourForeground.value);
if (selectPalette.value === "NEW_PALETTE") {
divNewPalette.style.display = "block";
} else {
divNewPalette.style.display = "none";
}
set_palette(selectPalette.value);
loadPreview();
});
function updateCustomPalette() {
set_palette(selectPalette.value, inputColourBackground.value, inputColourForeground.value);
loadPreview();
}
inputColourForeground.addEventListener("change", updateCustomPalette);
inputColourBackground.addEventListener("change", updateCustomPalette);
checkboxDither.addEventListener("change", () => {
set_dither(checkboxDither.checked);
loadPreview();

View File

@ -16,22 +16,11 @@ use colour_map::ColourMap;
const SD: u32 = 8;
enum SelectedPalette {
None,
Existing {
id: String,
},
New {
background: bitsy_parser::Colour,
foreground: bitsy_parser::Colour,
}
}
struct State {
game: Option<Game>,
image: Option<DynamicImage>,
room_name: Option<String>,
palette: SelectedPalette,
palette: Option<String>,
dither: bool,
brightness: i32,
}
@ -42,7 +31,7 @@ lazy_static! {
game: None,
image: None,
room_name: None,
palette: SelectedPalette::None,
palette: None,
dither: true,
brightness: 0,
}
@ -60,13 +49,8 @@ fn tile_name(prefix: &Option<String>, index: &u32) -> Option<String> {
#[wasm_bindgen]
pub fn load_default_game() {
let mut state = STATE.lock().unwrap();
state.game = Some(bitsy_parser::mock::game_default());
// yes, this will probably always just be "0", but to be safe…
state.palette = SelectedPalette::Existing {
id: bitsy_parser::mock::game_default().palette_ids()[0].clone()
}
state.palette = Some(bitsy_parser::mock::game_default().palette_ids()[0].clone())
}
#[wasm_bindgen]
@ -79,12 +63,12 @@ pub fn load_game(game_data: String) -> String {
Ok((game, _errs)) => {
let palette_id = game.palette_ids()[0].clone();
state.game = Some(game);
state.palette = SelectedPalette::Existing { id: palette_id };
state.palette = Some(palette_id);
format!("Loaded game")
},
_ => {
state.game = None;
state.palette = SelectedPalette::None;
state.palette = None;
format!("{}", result.err().unwrap())
}
}
@ -126,16 +110,12 @@ pub fn set_dither(dither: bool) {
}
#[wasm_bindgen]
pub fn set_palette(palette_id: &str, background: String, foreground: String) {
pub fn set_palette(palette_id: String) {
let mut state = STATE.lock().unwrap();
state.palette = match palette_id {
"NEW_PALETTE" => SelectedPalette::New {
background: bitsy_parser::Colour::from_hex(&background).unwrap(),
foreground: bitsy_parser::Colour::from_hex(&foreground).unwrap(),
},
"" => SelectedPalette::None,
_ => SelectedPalette::Existing { id: palette_id.to_string() },
match palette_id.is_empty() {
true => { state.palette = None },
false => { state.palette = Some(palette_id) },
}
}
@ -186,22 +166,10 @@ fn image_to_base64(image: &DynamicImage) -> String {
fn render_preview(state: &State) -> DynamicImage {
let mut buffer = state.image.as_ref().unwrap().clone().into_rgba();
let palette_id = state.palette.as_ref().unwrap();
let palette = *&state.game.as_ref().unwrap().get_palette(palette_id).unwrap();
let colour_map = crate::ColourMap::from(palette);
let palette = match &state.palette {
SelectedPalette::None => bitsy_parser::mock::game_default().palettes[0].clone(),
SelectedPalette::Existing { id } => state.game.as_ref().unwrap().get_palette(id).unwrap().clone(),
SelectedPalette::New { background, foreground } => Palette {
id: "0".to_string(),
name: None,
colours: vec![
background.clone(), foreground.clone(), Colour { red: 0, green: 0, blue: 0 }
],
},
};
let colour_map = crate::ColourMap::from(&palette);
// adjust brightness
let mut buffer = image::imageops::brighten(&mut buffer, state.brightness);
if state.dither {
@ -218,6 +186,17 @@ fn render_preview(state: &State) -> DynamicImage {
.expect("indexed color out-of-range")
.into()
});
let mut indexed = buffer.clone();
for (i, pixel) in buffer.pixels().enumerate() {
// todo get rid of magic numbers! what about Bitsy HD?
let mut pixel = image::Rgba::from(pixel.0);
colour_map.map_color(&mut pixel);
indexed.put_pixel(
(i % 128) as u32,
(i / 128) as u32,
pixel
);
}
}
image::DynamicImage::ImageRgba8(buffer)