diff --git a/raws/props.json b/raws/props.json index 0c48291..f60ff11 100644 --- a/raws/props.json +++ b/raws/props.json @@ -2,7 +2,7 @@ { "id": "door", "name": "door", - "renderable": { "glyph": "+", "fg": "#00FFFF", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "+", "sprite": 17, "fg": "#00FFFF", "bg": "#000000", "order": 2 }, "flags": ["DOOR"] }, { @@ -21,7 +21,7 @@ { "id": "prop_table", "name": "table", - "renderable": { "glyph": "-", "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "-", "sprite": 52, "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, "flags": [] }, { @@ -33,25 +33,25 @@ { "id": "prop_statue", "name": "statue", - "renderable": { "glyph": "@", "fg": "#ffffff", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "@", "sprite": 29, "fg": "#ffffff", "bg": "#000000", "order": 2 }, "flags": [] }, { "id": "prop_bed", "name": "bed", - "renderable": { "glyph": "=", "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "=", "sprite": 50, "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, "flags": [] }, { "id": "prop_chair", "name": "chair", - "renderable": { "glyph": "└", "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "└", "sprite": 51, "fg": "#AAAAAA", "bg": "#000000", "order": 2 }, "flags": [] }, { "id": "prop_candle", "name": "candle", - "renderable": { "glyph": "Ä", "fg": "#FFA500", "bg": "#000000", "order": 2 }, + "renderable": { "glyph": "Ä", "sprite": 3, "fg": "#FFA500", "bg": "#000000", "order": 2 }, "flags": [] }, { diff --git a/resources/curses11x20.png b/resources/curses11x20.png new file mode 100644 index 0000000..5f5e1e5 Binary files /dev/null and b/resources/curses11x20.png differ diff --git a/resources/curses12x24.png b/resources/curses12x24.png new file mode 100644 index 0000000..4504d0a Binary files /dev/null and b/resources/curses12x24.png differ diff --git a/resources/curses16x16.pdn b/resources/curses16x16.pdn new file mode 100644 index 0000000..a13f60d Binary files /dev/null and b/resources/curses16x16.pdn differ diff --git a/resources/curses16x16.png b/resources/curses16x16.png new file mode 100644 index 0000000..042abea Binary files /dev/null and b/resources/curses16x16.png differ diff --git a/resources/curses8x16.pdn b/resources/curses8x16.pdn new file mode 100644 index 0000000..02b2112 Binary files /dev/null and b/resources/curses8x16.pdn differ diff --git a/resources/curses8x16.png b/resources/curses8x16.png new file mode 100644 index 0000000..4b83036 Binary files /dev/null and b/resources/curses8x16.png differ diff --git a/resources/healthbar11x2.png b/resources/healthbar11x2.png new file mode 100644 index 0000000..96fb67c Binary files /dev/null and b/resources/healthbar11x2.png differ diff --git a/resources/healthbar22x2.png b/resources/healthbar22x2.png new file mode 100644 index 0000000..daa15d1 Binary files /dev/null and b/resources/healthbar22x2.png differ diff --git a/resources/nagidal22x20_centred.png b/resources/nagidal22x20_centred.png new file mode 100644 index 0000000..1383fb9 Binary files /dev/null and b/resources/nagidal22x20_centred.png differ diff --git a/resources/nagidal22x22_centred.png b/resources/nagidal22x22_centred.png new file mode 100644 index 0000000..f941b27 Binary files /dev/null and b/resources/nagidal22x22_centred.png differ diff --git a/resources/nagidal24x24.png b/resources/nagidal24x24.png new file mode 100644 index 0000000..2d4aba9 Binary files /dev/null and b/resources/nagidal24x24.png differ diff --git a/resources/terminal10x10_gs_tc.png b/resources/terminal10x10_gs_tc.png new file mode 100644 index 0000000..5e0cdc9 Binary files /dev/null and b/resources/terminal10x10_gs_tc.png differ diff --git a/resources/vga8x16.png b/resources/vga8x16.png new file mode 100644 index 0000000..913e32c Binary files /dev/null and b/resources/vga8x16.png differ diff --git a/resources/world16x16.png b/resources/world16x16.png new file mode 100644 index 0000000..e05e1d5 Binary files /dev/null and b/resources/world16x16.png differ diff --git a/src/ai/approach_ai_system.rs b/src/ai/approach_ai_system.rs index c3cc2ca..6e6e7a8 100644 --- a/src/ai/approach_ai_system.rs +++ b/src/ai/approach_ai_system.rs @@ -45,6 +45,7 @@ impl<'a> System<'a> for ApproachAI { continue; }; let mut path: Option = None; + let mut curr_abs_diff = 100; let idx = map.xy_idx(pos.x, pos.y); for tar_idx in target_idxs { let potential_path = a_star_search(idx, tar_idx, &mut *map); @@ -54,6 +55,17 @@ impl<'a> System<'a> for ApproachAI { potential_path.steps.len() < path.as_ref().unwrap().steps.len() { path = Some(potential_path); + let (x1, y1) = (pos.x, pos.y); + let (x2, y2) = ((tar_idx as i32) % map.width, (tar_idx as i32) / map.width); + curr_abs_diff = i32::abs(x2 - x1) + i32::abs(y2 - y1); + } else if potential_path.steps.len() == path.as_ref().unwrap().steps.len() { + let (x1, y1) = (pos.x, pos.y); + let (x2, y2) = ((tar_idx as i32) % map.width, (tar_idx as i32) / map.width); + let abs_diff = i32::abs(x2 - x1) + i32::abs(y2 - y1); + if abs_diff < curr_abs_diff { + path = Some(potential_path); + curr_abs_diff = abs_diff; + } } } } diff --git a/src/camera.rs b/src/camera.rs index 00b6869..090476b 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,14 +1,16 @@ -use super::{ Hidden, Map, Mind, Position, Prop, Renderable }; +use super::{ Hidden, Map, Mind, Position, Prop, Renderable, Pools }; use bracket_lib::prelude::*; use specs::prelude::*; use std::ops::Mul; +use super::data::visuals::{ VIEWPORT_W, VIEWPORT_H }; +use super::data::prelude::*; const SHOW_BOUNDARIES: bool = false; pub fn get_screen_bounds(ecs: &World, _ctx: &mut BTerm) -> (i32, i32, i32, i32, i32, i32) { let player_pos = ecs.fetch::(); let map = ecs.fetch::(); - let (x_chars, y_chars, mut x_offset, mut y_offset) = (69, 41, 1, 10); + let (x_chars, y_chars, mut x_offset, mut y_offset) = (VIEWPORT_W, VIEWPORT_H, 1, 10); let centre_x = (x_chars / 2) as i32; let centre_y = (y_chars / 2) as i32; @@ -43,13 +45,29 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) { if t_x >= 0 && t_x < map.width && t_y >= 0 && t_y < map.height { let idx = map.xy_idx(t_x, t_y); if map.revealed_tiles[idx] { - let (glyph, fg, bg) = crate::map::themes::get_tile_renderables_for_id( - idx, - &*map, - Some(*ecs.fetch::()), - None - ); - ctx.set(x + x_offset, y + y_offset, fg, bg, glyph); + if 1 == 2 { + let (glyph, fg, bg) = crate::map::themes::get_tile_renderables_for_id( + idx, + &*map, + Some(*ecs.fetch::()), + None + ); + ctx.set(x + x_offset, y + y_offset, fg, bg, glyph); + } else { + ctx.set_active_console(0); + let (id, tint) = crate::map::themes::get_sprite_for_id( + idx, + &*map, + Some(*ecs.fetch::()) + ); + ctx.add_sprite( + Rect::with_size(x * 16 + x_offset * 16, y * 16 + y_offset * 16, 16, 16), + 0, + tint, + id + ); + ctx.set_active_console(TILE_LAYER); + } } } else if SHOW_BOUNDARIES { ctx.set( @@ -67,8 +85,11 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) { // Render entities { + ctx.set_active_console(ENTITY_LAYER); + let positions = ecs.read_storage::(); let renderables = ecs.read_storage::(); + let pools = ecs.read_storage::(); let minds = ecs.read_storage::(); let hidden = ecs.read_storage::(); let props = ecs.write_storage::(); @@ -84,12 +105,7 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) { if pos.x < max_x && pos.y < max_y && pos.x >= min_x && pos.y >= min_y { let mut draw = false; let mut fg = render.fg; - let mut bg = crate::map::themes::get_tile_renderables_for_id( - idx, - &*map, - Some(*ecs.fetch::()), - None - ).2; + let bg = BLACK; // Draw entities on visible tiles if map.visible_tiles[idx] { draw = true; @@ -104,9 +120,6 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) { let has_mind = minds.get(*ent); if let Some(_) = has_mind { draw = true; - if !map.revealed_tiles[idx] { - bg = RGB::named(BLACK); - } } } } @@ -118,16 +131,51 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) { } } if draw { - ctx.set( - entity_offset_x + x_offset, - entity_offset_y + y_offset, - fg, - bg, - render.glyph - ); + if let Some(sprite) = render.sprite { + ctx.set_active_console(0); + ctx.add_sprite( + Rect::with_size( + entity_offset_x * 16 + x_offset * 16, + entity_offset_y * 16 + y_offset * 16, + 16, + 16 + ), + render.render_order, + RGBA::named(WHITE), + sprite + ); + ctx.set_active_console(ENTITY_LAYER); + } else { + ctx.set( + entity_offset_x + x_offset, + entity_offset_y + y_offset, + fg, + bg, + render.glyph + ); + } + if let Some(pool) = pools.get(*ent) { + if pool.hit_points.current < pool.hit_points.max { + ctx.set_active_console(HP_BAR_LAYER); + crate::gui::draw_lerping_bar( + ctx, + (entity_offset_x + x_offset) * 16 + 2, + (entity_offset_y + y_offset) * 16 - 1, + 14, + pool.hit_points.current, + pool.hit_points.max, + RGB::named(GREEN), + RGB::named(RED), + false, + false + ); + ctx.set_active_console(ENTITY_LAYER); + } + } } } } + ctx.set_active_console(TILE_LAYER); } } diff --git a/src/components.rs b/src/components.rs index 8c56cce..b489abe 100644 --- a/src/components.rs +++ b/src/components.rs @@ -41,6 +41,7 @@ pub struct OtherLevelPosition { #[derive(Component, ConvertSaveload, Clone)] pub struct Renderable { pub glyph: FontCharType, + pub sprite: Option, pub fg: RGB, pub bg: RGB, pub render_order: i32, diff --git a/src/data/mod.rs b/src/data/mod.rs index 8abda34..cefe83f 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -5,3 +5,8 @@ pub mod char_create; pub mod events; pub mod ids; pub mod names; +pub mod sprites; + +pub mod prelude { + pub use super::visuals::{ TILE_LAYER, ENTITY_LAYER, TEXT_LAYER, HP_BAR_LAYER }; +} diff --git a/src/data/sprites.rs b/src/data/sprites.rs new file mode 100644 index 0000000..1b9d7bf --- /dev/null +++ b/src/data/sprites.rs @@ -0,0 +1,119 @@ +// Row 1 +pub const UNKN: usize = 0; +pub const UNKN2: usize = 1; +pub const UNKN3: usize = 2; +pub const CANDLE: usize = 3; +pub const CANDLE2: usize = 4; +pub const CANDLE3: usize = 5; +pub const CANDLE4: usize = 6; +pub const CANDLE5: usize = 7; +pub const CANDLE6: usize = 8; +pub const CAULDRON: usize = 9; +pub const CAULDRON2: usize = 10; +pub const POTS: usize = 11; +pub const POTS2: usize = 12; +pub const POT: usize = 13; +pub const SPIKES: usize = 14; +pub const SPIKES2: usize = 15; +// Row 2 +pub const WINDOW: usize = 16; +pub const DOOR: usize = 17; +pub const DOOR_OPEN: usize = 18; +pub const ROOF_BASE: usize = 19; +pub const ROOF_BASE2: usize = 20; +pub const ROOF: usize = 21; +pub const ROOF2: usize = 22; +pub const ROOF_CHIMNEY: usize = 23; +pub const SIGN: usize = 24; +pub const SIGN_BLACKSMITH: usize = 25; +pub const SIGN_POTION: usize = 26; +pub const SIGN_FURNITURE: usize = 27; +pub const WINDOW_LIT: usize = 28; +pub const STATUE_ANGEL: usize = 29; +pub const STATUE: usize = 30; +pub const STATUE_SPIDER: usize = 31; +// Row 3 +pub const UNKN4: usize = 32; +pub const UNKN5: usize = 33; +pub const UNKN6: usize = 34; +pub const UNKN7: usize = 35; +pub const UNKN8: usize = 36; +pub const TREE: usize = 37; +pub const TREE2: usize = 38; +pub const PATH_GRASS: usize = 39; +pub const PATH_GRASS_QUAD: usize = 40; +pub const PATH_GRASS_QUAD2: usize = 41; +pub const PATH_GRASS_QUAD3: usize = 42; +pub const CAMPFIRE: usize = 43; +pub const CAMPFIRE_LIT: usize = 44; +pub const CAMPFIRE_LIT2: usize = 45; // ANIMATE WITH % 2 AND SOMETHING TO DO WITH FRAME TIME +pub const THRONE: usize = 46; +pub const THRONE2: usize = 47; +// Row 4 +pub const BOOKSHELF: usize = 48; +pub const BOOKSHELF_EMPTY: usize = 49; +pub const BED: usize = 50; +pub const CHAIR: usize = 51; +pub const TABLE: usize = 52; +pub const TABLE_L: usize = 53; +pub const TABLE_M: usize = 54; +pub const TABLE_R: usize = 55; +pub const CHAIR_AT_TABLE_L: usize = 56; +pub const TABLE_M_PARCHMENT: usize = 57; +pub const CHAIR_AT_TABLE_R: usize = 58; +pub const TABLE_DARK: usize = 59; +pub const TABLE_DARK_SKULL: usize = 60; +pub const TABLE_DARK_L: usize = 61; +pub const TABLE_DARK_M: usize = 62; +pub const TABLE_DARK_R: usize = 63; +// Row 5 +pub const GRASS: usize = 64; +pub const GRASS2: usize = 65; +pub const GRASS3: usize = 66; +pub const GRASS4: usize = 67; +pub const GRASS5: usize = 68; +pub const MUSHROOM: usize = 69; +pub const MUSHROOM_PURPLE: usize = 70; +pub const MUSHROOM_ORANGE: usize = 71; +pub const LILYPAD: usize = 72; +pub const LILYPAD2: usize = 73; +pub const LILYPAD3: usize = 74; +pub const LILYPAD4: usize = 75; +pub const LILYPAD5: usize = 76; +pub const LILYPAD6: usize = 77; +pub const LILYPAD7: usize = 78; +pub const LILYPAD8: usize = 79; +// Row 6 (80-95) +// Row 7 (96-111) +// Row 8 (112-127) +pub const FLOOR_WOOD: usize = 124; +// Row 9 (128-143) +// Row 10 (144-159) +// Row 11 (160-175) +pub const WATER_DEEP: usize = 164; +// Row 12 (176-191) +// Row 13 (192-207) +// Row 14 (208-223) +pub const FLOOR_GRASS: usize = 216; +// Row 15 (224-239) +pub const FLOOR: usize = 224; +// Row 16 (240-255) +// Row 17 (256-271) +// Row 18 (272-287) +// Row 19 (288-303) +pub const WALL_BASE: usize = 288; +pub const WALL_BASE2: usize = 289; +pub const WALL_BASE3: usize = 290; +pub const WALL_BASE4: usize = 291; +pub const WALL_CLOTH_BASE: usize = 292; +pub const WALL_CRACKED_BASE: usize = 293; +pub const WALL: usize = 294; +pub const WALL2: usize = 295; +pub const WALL3: usize = 296; +pub const WALL4: usize = 297; +pub const WALL_CRACKED: usize = 298; +pub const WALL_CLOTH_H: usize = 299; +pub const STAIR_D: usize = 300; +pub const STAIR_A: usize = 301; +pub const BASIN: usize = 302; +pub const BASIN_EMPTY: usize = 303; diff --git a/src/data/visuals.rs b/src/data/visuals.rs index 8f59a24..26fa5ee 100644 --- a/src/data/visuals.rs +++ b/src/data/visuals.rs @@ -2,6 +2,13 @@ use bracket_lib::prelude::*; // POST-PROCESSING pub const WITH_DARKEN_BY_DISTANCE: bool = true; // If further away tiles should get darkened, instead of a harsh transition to non-visible. +pub const VIEWPORT_W: i32 = 69; +pub const VIEWPORT_H: i32 = 41; + +pub const TILE_LAYER: usize = 1; +pub const ENTITY_LAYER: usize = 2; +pub const TEXT_LAYER: usize = 3; +pub const HP_BAR_LAYER: usize = 4; pub const BRIGHTEN_FG_COLOUR_BY: i32 = 16; pub const GLOBAL_OFFSET_MIN_CLAMP: f32 = -0.5; diff --git a/src/effects/damage.rs b/src/effects/damage.rs index 80885e2..74d1178 100644 --- a/src/effects/damage.rs +++ b/src/effects/damage.rs @@ -184,7 +184,7 @@ fn get_death_message(ecs: &World, source: Entity) -> String { result.push_str(format!("{}", PLAYER_DIED_SUICIDE).as_str()); } else if let Some(name) = ecs.read_storage::().get(source) { result.push_str( - format!("{} {}", PLAYER_DIED_NAMED_ATTACKER, with_article(name.name.clone())).as_str() + format!("{} {}", PLAYER_DIED_NAMED_ATTACKER, with_article(&name.name)).as_str() ); } else { result.push_str(format!("{}", PLAYER_DIED_UNKNOWN).as_str()); diff --git a/src/gui/character_creation.rs b/src/gui/character_creation.rs index da1ecdb..bc6e68e 100644 --- a/src/gui/character_creation.rs +++ b/src/gui/character_creation.rs @@ -28,6 +28,7 @@ use bracket_lib::prelude::*; use serde::{ Deserialize, Serialize }; use specs::prelude::*; use std::collections::HashMap; +use crate::data::prelude::*; #[derive(Serialize, Deserialize, Copy, Clone, PartialEq)] pub enum Ancestry { @@ -112,6 +113,7 @@ pub enum CharCreateResult { /// Handles the player character creation screen. pub fn character_creation(gs: &mut State, ctx: &mut BTerm) -> CharCreateResult { + ctx.set_active_console(TEXT_LAYER); let runstate = gs.ecs.fetch::(); let mut x = 2; @@ -245,6 +247,7 @@ pub fn character_creation(gs: &mut State, ctx: &mut BTerm) -> CharCreateResult { } } } + ctx.set_active_console(TILE_LAYER); return CharCreateResult::NoSelection { ancestry: Ancestry::Human, class: Class::Fighter }; } @@ -270,6 +273,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) { renderables .insert(*player, Renderable { glyph: to_cp437(DWARF_GLYPH), + sprite: None, // TODO: Dwarf sprite fg: RGB::named(DWARF_COLOUR), bg: RGB::named(BLACK), render_order: 0, @@ -281,6 +285,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) { renderables .insert(*player, Renderable { glyph: to_cp437(ELF_GLYPH), + sprite: None, // TODO: Elf sprite fg: RGB::named(ELF_COLOUR), bg: RGB::named(BLACK), render_order: 0, @@ -306,6 +311,7 @@ pub fn setup_player_ancestry(ecs: &mut World, ancestry: Ancestry) { renderables .insert(*player, Renderable { glyph: to_cp437(CATFOLK_GLYPH), + sprite: None, // TODO: Catfolk sprite fg: RGB::named(CATFOLK_COLOUR), bg: RGB::named(BLACK), render_order: 0, diff --git a/src/gui/farlook.rs b/src/gui/farlook.rs index c8f6312..045b172 100644 --- a/src/gui/farlook.rs +++ b/src/gui/farlook.rs @@ -1,4 +1,11 @@ -use super::{ State, RunState, tooltip::draw_tooltips, camera::get_screen_bounds }; +use super::{ + State, + RunState, + tooltip::draw_tooltips, + camera::get_screen_bounds, + VIEWPORT_H, + VIEWPORT_W, +}; use bracket_lib::prelude::*; #[derive(PartialEq, Copy, Clone)] @@ -23,9 +30,8 @@ pub fn show_farlook(gs: &mut State, ctx: &mut BTerm) -> FarlookResult { ); if let RunState::Farlook { x, y } = *runstate { - let (screen_x, screen_y) = (69, 41); - let x = x.clamp(x_offset, x_offset - 1 + (screen_x as i32)); - let y = y.clamp(y_offset, y_offset - 1 + (screen_y as i32)); + let x = x.clamp(x_offset, x_offset - 1 + VIEWPORT_W); + let y = y.clamp(y_offset, y_offset - 1 + VIEWPORT_H); ctx.set(x, y, RGB::named(WHITE), RGB::named(BLACK), to_cp437('X')); draw_tooltips(&gs.ecs, ctx, Some((x, y))); diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 13e32d0..65482af 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -34,12 +34,15 @@ use super::{ BUC, data::ids::get_local_col, }; +use crate::data::prelude::*; use crate::data::entity::CARRY_CAPACITY_PER_STRENGTH; use crate::data::visuals::{ TARGETING_LINE_COL, TARGETING_CURSOR_COL, TARGETING_AOE_COL, TARGETING_VALID_COL, + VIEWPORT_W, + VIEWPORT_H, }; use bracket_lib::prelude::*; use specs::prelude::*; @@ -82,26 +85,33 @@ pub fn draw_lerping_bar( n: i32, max: i32, full_colour: RGB, - empty_colour: RGB + empty_colour: RGB, + with_text: bool, + with_bg: bool ) { let percent = (n as f32) / (max as f32); let fill_width = (percent * (width as f32)) as i32; let bg = empty_colour.lerp(full_colour, percent); - let fg = RGB::named(BLACK); + let black = RGB::named(BLACK); for x in 0..width { if x <= fill_width { - ctx.print_color(sx + x, sy, fg, bg, " "); - } else { - ctx.print_color(sx + x, sy, RGB::named(BLACK), RGB::named(BLACK), " "); + ctx.print_color(sx + x, sy, black, bg, ' '); + } else if with_bg { + ctx.print_color(sx + x, sy, black, black, ' '); } } - ctx.print(sx - 1, sy, "["); - let health = format!("{}/{}", n, max); - ctx.print_color(sx + 1, sy, fg, bg, health); - ctx.print(sx + width, sy, "]"); + if with_text { + ctx.print(sx - 1, sy, "["); + let health = format!("{}/{}", n, max); + ctx.print_color(sx + 1, sy, black, bg, health); + ctx.print(sx + width, sy, "]"); + } } +pub const TEXT_FONT_MOD: i32 = 2; + pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { + ctx.set_active_console(TEXT_LAYER); // Render stats let pools = ecs.read_storage::(); let attributes = ecs.read_storage::(); @@ -119,23 +129,27 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { // Draw hp/mana bars draw_lerping_bar( ctx, - 2, + 2 * TEXT_FONT_MOD, 53, - 22, + 22 * TEXT_FONT_MOD, stats.hit_points.current, stats.hit_points.max, RGB::from_u8(0, 255, 0), - RGB::from_u8(255, 0, 0) + RGB::from_u8(255, 0, 0), + true, + true ); draw_lerping_bar( ctx, - 2, + 2 * TEXT_FONT_MOD, 54, - 22, + 22 * TEXT_FONT_MOD, stats.mana.current, stats.mana.max, RGB::named(BLUE), - RGB::named(BLACK) + RGB::named(BLACK), + true, + true ); // Draw AC let skill_ac_bonus = gamesystem::skill_bonus(Skill::Defence, &*skills); @@ -150,18 +164,18 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { } let armour_class = stats.bac - attributes.dexterity.bonus / 2 - skill_ac_bonus - armour_ac_bonus; - ctx.print_color(26, 53, RGB::named(PINK), RGB::named(BLACK), "AC"); - ctx.print_color(28, 53, RGB::named(WHITE), RGB::named(BLACK), armour_class); + ctx.print_color(26 * TEXT_FONT_MOD, 53, RGB::named(PINK), RGB::named(BLACK), "AC"); + ctx.print_color(28 * TEXT_FONT_MOD, 53, RGB::named(WHITE), RGB::named(BLACK), armour_class); // Draw level ctx.print_color( - 26, + 26 * TEXT_FONT_MOD, 54, RGB::named(WHITE), RGB::named(BLACK), format!("XP{}/{}", stats.level, stats.xp) ); // Draw attributes - let x = 38; + let x = 38 * TEXT_FONT_MOD; ctx.print_color(x, 53, RGB::named(RED), RGB::named(BLACK), "STR"); ctx.print_color(x + 3, 53, RGB::named(WHITE), RGB::named(BLACK), attributes.strength.base); ctx.print_color(x + 7, 53, RGB::named(GREEN), RGB::named(BLACK), "DEX"); @@ -196,7 +210,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { match hunger.state { HungerState::Satiated => { ctx.print_color_right( - 70, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, 53, get_hunger_colour(hunger.state), RGB::named(BLACK), @@ -206,7 +220,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { HungerState::Normal => {} HungerState::Hungry => { ctx.print_color_right( - 70, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, 53, get_hunger_colour(hunger.state), RGB::named(BLACK), @@ -215,7 +229,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { } HungerState::Weak => { ctx.print_color_right( - 70, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, 53, get_hunger_colour(hunger.state), RGB::named(BLACK), @@ -224,7 +238,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { } HungerState::Fainting => { ctx.print_color_right( - 70, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, 53, get_hunger_colour(hunger.state), RGB::named(BLACK), @@ -233,7 +247,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { } HungerState::Starving => { ctx.print_color_right( - 70, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, 53, get_hunger_colour(hunger.state), RGB::named(BLACK), @@ -246,7 +260,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { match burden.level { crate::BurdenLevel::Burdened => { ctx.print_color_right( - 70, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, 50, RGB::named(BROWN1), RGB::named(BLACK), @@ -255,7 +269,7 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { } crate::BurdenLevel::Strained => { ctx.print_color_right( - 70, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, 50, RGB::named(ORANGE), RGB::named(BLACK), @@ -263,12 +277,24 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { ); } crate::BurdenLevel::Overloaded => { - ctx.print_color_right(70, 50, RGB::named(RED), RGB::named(BLACK), "Overloaded"); + ctx.print_color_right( + (VIEWPORT_W + 1) * TEXT_FONT_MOD, + 50, + RGB::named(RED), + RGB::named(BLACK), + "Overloaded" + ); } } } if stats.god { - ctx.print_color(20, 20, RGB::named(YELLOW), RGB::named(BLACK), "--- GODMODE: ON ---"); + ctx.print_color( + 20 * TEXT_FONT_MOD, + 20, + RGB::named(YELLOW), + RGB::named(BLACK), + "--- GODMODE: ON ---" + ); } // Draw equipment let renderables = ecs.read_storage::(); @@ -286,16 +312,34 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { } let mut y = 1; if !equipment.is_empty() { - ctx.print_color(72, y, RGB::named(BLACK), RGB::named(WHITE), "Equipment"); + ctx.print_color( + (VIEWPORT_W + 3) * TEXT_FONT_MOD, + y, + RGB::named(BLACK), + RGB::named(WHITE), + "Equipment" + ); let mut j = 0; for item in equipment { y += 1; - ctx.set(72, y, RGB::named(YELLOW), RGB::named(BLACK), 97 + (j as FontCharType)); + ctx.set( + (VIEWPORT_W + 3) * TEXT_FONT_MOD, + y, + RGB::named(YELLOW), + RGB::named(BLACK), + 97 + (j as FontCharType) + ); j += 1; - ctx.set(74, y, item.2, RGB::named(BLACK), item.3); - ctx.print_color(76, y, item.1, RGB::named(BLACK), &item.0); + ctx.set((VIEWPORT_W + 3) * TEXT_FONT_MOD + 2, y, item.2, RGB::named(BLACK), item.3); ctx.print_color( - 76 + &item.0.len() + 1, + (VIEWPORT_W + 3) * TEXT_FONT_MOD + 4, + y, + item.1, + RGB::named(BLACK), + &item.0 + ); + ctx.print_color( + (VIEWPORT_W + 3) * TEXT_FONT_MOD + 4 + (item.0.len() as i32) + 1, y, RGB::named(WHITE), RGB::named(BLACK), @@ -306,9 +350,15 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { } // Draw consumables - ctx.print_color(72, y, RGB::named(BLACK), RGB::named(WHITE), "Backpack"); ctx.print_color( - 81, + (VIEWPORT_W + 3) * TEXT_FONT_MOD, + y, + RGB::named(BLACK), + RGB::named(WHITE), + "Backpack" + ); + ctx.print_color( + (VIEWPORT_W + 12) * TEXT_FONT_MOD, y, RGB::named(WHITE), RGB::named(BLACK), @@ -321,25 +371,31 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { ); y += 1; let player_inventory = get_player_inventory(&ecs); - y = print_options(&player_inventory, 72, y, ctx).0; + y = print_options(&player_inventory, (VIEWPORT_W + 3) * TEXT_FONT_MOD, y, ctx).0; // Draw spells - if we have any -- NYI! if let Some(known_spells) = ecs.read_storage::().get(*player_entity) { y += 1; // Draw known spells - ctx.print_color(72, y, RGB::named(BLACK), RGB::named(WHITE), "Known Spells"); + ctx.print_color( + (VIEWPORT_W + 3) * TEXT_FONT_MOD, + y, + RGB::named(BLACK), + RGB::named(WHITE), + "Known Spells" + ); y += 1; let mut index = 1; for spell in known_spells.list.iter() { ctx.print_color( - 72, + (VIEWPORT_W + 3) * TEXT_FONT_MOD, y, RGB::named(YELLOW), RGB::named(BLACK), &format!("{}", index) ); ctx.print_color( - 74, + (VIEWPORT_W + 3) * TEXT_FONT_MOD + 2, y, RGB::named(CYAN), RGB::named(BLACK), @@ -396,22 +452,34 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { if !seen_entities.is_empty() { y += 1; - ctx.print_color(72, y, RGB::named(BLACK), RGB::named(WHITE), "In View"); + ctx.print_color( + (VIEWPORT_W + 3) * TEXT_FONT_MOD, + y, + RGB::named(BLACK), + RGB::named(WHITE), + "In View" + ); for entity in seen_entities { y += 1; - ctx.set(72, y, entity.2, RGB::named(BLACK), entity.3); - ctx.print_color(74, y, entity.1, RGB::named(BLACK), entity.0); + ctx.set((VIEWPORT_W + 3) * TEXT_FONT_MOD, y, entity.2, RGB::named(BLACK), entity.3); + ctx.print_color( + (VIEWPORT_W + 3) * TEXT_FONT_MOD + 2, + y, + entity.1, + RGB::named(BLACK), + entity.0 + ); } } } // Render the message log at [1, 7], ascending, with 7 lines and a max width of 68. gamelog::print_log( - &mut BACKEND_INTERNAL.lock().consoles[0].console, - Point::new(1, 7), + &mut BACKEND_INTERNAL.lock().consoles[TEXT_LAYER].console, + Point::new(1 * TEXT_FONT_MOD, 7), false, 7, - 68 + (VIEWPORT_W - 1) * TEXT_FONT_MOD ); // Render id @@ -421,12 +489,18 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { } else { format!("{}", map.short_name) }; - ctx.print_color_right(70, 54, get_local_col(map.id), RGB::named(BLACK), &id); + ctx.print_color_right( + (VIEWPORT_W + 1) * TEXT_FONT_MOD, + 54, + get_local_col(map.id), + RGB::named(BLACK), + &id + ); // Render turn let turns = crate::gamelog::get_event_count(EVENT::COUNT_TURN); ctx.print_color_right( - 69 - id.len(), + VIEWPORT_W * TEXT_FONT_MOD - (id.len() as i32), 54, RGB::named(YELLOW), RGB::named(BLACK), @@ -434,10 +508,39 @@ pub fn draw_ui(ecs: &World, ctx: &mut BTerm) { ); // Boxes and tooltips last, so they draw over everything else. - ctx.draw_hollow_box(0, 0, 70, 8, RGB::named(WHITE), RGB::named(BLACK)); // Log box - ctx.draw_hollow_box(0, 9, 70, 42, RGB::named(WHITE), RGB::named(BLACK)); // Camera box - ctx.draw_hollow_box(0, 52, 70, 3, RGB::named(WHITE), RGB::named(BLACK)); // Stats box - ctx.draw_hollow_box(71, 0, 33, 55, RGB::named(WHITE), RGB::named(BLACK)); // Side box + ctx.draw_hollow_box( + 0 * TEXT_FONT_MOD, + 0, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, + 8, + RGB::named(WHITE), + RGB::named(BLACK) + ); // Log box + ctx.draw_hollow_box( + 0 * TEXT_FONT_MOD, + 9, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, + 42, + RGB::named(WHITE), + RGB::named(BLACK) + ); // Camera box + ctx.draw_hollow_box( + 0 * TEXT_FONT_MOD, + 52, + (VIEWPORT_W + 1) * TEXT_FONT_MOD, + 3, + RGB::named(WHITE), + RGB::named(BLACK) + ); // Stats box + ctx.draw_hollow_box( + (VIEWPORT_W + 2) * TEXT_FONT_MOD, + 0, + 33 * TEXT_FONT_MOD, + 55, + RGB::named(WHITE), + RGB::named(BLACK) + ); // Side box + ctx.set_active_console(TILE_LAYER); tooltip::draw_tooltips(ecs, ctx, None); } @@ -571,10 +674,9 @@ pub fn print_options( pub fn get_max_inventory_width(inventory: &PlayerInventory) -> i32 { let mut width: i32 = 0; for (item, (_e, count)) in inventory { - let mut this_width = item.display_name.singular.len() as i32; - // Clean this up. It should use consts. - this_width += 4; // The spaces before and after the character to select this item, etc. + let mut this_width = 4; // The spaces before and after the character to select this item, etc. if count <= &1 { + this_width += item.display_name.singular.len() as i32; if item.display_name.singular == item.display_name.plural { this_width += 4; // "some".len } else if @@ -585,6 +687,7 @@ pub fn get_max_inventory_width(inventory: &PlayerInventory) -> i32 { this_width += 1; // "a".len } } else { + this_width += item.display_name.plural.len() as i32; this_width += count.to_string().len() as i32; // i.e. "12".len } width = if width > this_width { width } else { this_width }; @@ -897,10 +1000,12 @@ pub fn get_player_inventory(ecs: &World) -> PlayerInventory { } pub fn show_inventory(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Option) { + ctx.set_active_console(TEXT_LAYER); + let player_inventory = get_player_inventory(&gs.ecs); let count = player_inventory.len(); - let (x_offset, y_offset) = (1, 10); + let (x_offset, y_offset) = (1 * TEXT_FONT_MOD, 10); let on_overmap = gs.ecs.fetch::().overmap; let message = if !on_overmap { @@ -917,6 +1022,8 @@ pub fn show_inventory(gs: &mut State, ctx: &mut BTerm) -> (ItemMenuResult, Optio ctx.draw_box(x, y, width + 2, (count + 1) as i32, RGB::named(WHITE), RGB::named(BLACK)); print_options(&player_inventory, x + 1, y + 1, ctx); + ctx.set_active_console(TILE_LAYER); + match ctx.key { None => (ItemMenuResult::NoResponse, None), Some(key) => @@ -1128,9 +1235,8 @@ pub fn ranged_target( &gs.ecs, ctx ); - let (screen_x, screen_y) = (69, 41); - let x = x.clamp(x_offset, x_offset - 1 + (screen_x as i32)); - let y = y.clamp(y_offset, y_offset - 1 + (screen_y as i32)); + let x = x.clamp(x_offset, x_offset - 1 + VIEWPORT_W); + let y = y.clamp(y_offset, y_offset - 1 + VIEWPORT_H); let mut mouse_pos_adjusted = mouse_pos; mouse_pos_adjusted.0 += min_x - x_offset; @@ -1446,7 +1552,7 @@ pub fn game_over(ctx: &mut BTerm) -> YesNoResult { } } -pub fn with_article(name: String) -> String { +pub fn with_article(name: &String) -> String { // If first letter is a capital if name.chars().nth(0).unwrap().is_uppercase() { return format!("{}", name); diff --git a/src/gui/tooltip.rs b/src/gui/tooltip.rs index e11d50f..1aebed0 100644 --- a/src/gui/tooltip.rs +++ b/src/gui/tooltip.rs @@ -12,6 +12,7 @@ use super::{ }; use crate::TileType; use crate::data::ids::*; +use crate::data::prelude::*; use bracket_lib::prelude::*; use specs::prelude::*; @@ -45,6 +46,7 @@ impl Tooltip { return (self.lines.len() as i32) + 2i32; } fn render(&self, ctx: &mut BTerm, x: i32, y: i32) { + ctx.set_active_console(TEXT_LAYER); ctx.draw_box( x, y, @@ -56,6 +58,7 @@ impl Tooltip { for (i, s) in self.lines.iter().enumerate() { ctx.print_color(x + 1, y + (i as i32) + 1, s.1, RGB::named(BLACK), &s.0); } + ctx.set_active_console(TILE_LAYER); } } @@ -169,13 +172,15 @@ pub fn draw_tooltips(ecs: &World, ctx: &mut BTerm, xy: Option<(i32, i32)>) { if mouse_pos.0 > 35 { // Render to the left arrow = to_cp437('→'); - arrow_x = mouse_pos.0 - 1; + arrow_x = mouse_pos.0 * 2 - 1; } else { // Render to the right arrow = to_cp437('←'); - arrow_x = mouse_pos.0 + 1; + arrow_x = (mouse_pos.0 + 1) * 2; } + ctx.set_active_console(TEXT_LAYER); ctx.set(arrow_x, arrow_y, white, RGB::named(BLACK), arrow); + ctx.set_active_console(TILE_LAYER); let mut total_height = 0; for t in tooltips.iter() { @@ -189,9 +194,9 @@ pub fn draw_tooltips(ecs: &World, ctx: &mut BTerm, xy: Option<(i32, i32)>) { for t in tooltips.iter() { let x = if mouse_pos.0 > 35 { - mouse_pos.0 - (1 + t.width()) + (mouse_pos.0 * 2) - (1 + t.width()) } else { - mouse_pos.0 + (1 + 1) + (mouse_pos.0 * 2) + 2 + 1 }; t.render(ctx, x, y); y += t.height(); diff --git a/src/main.rs b/src/main.rs index f82ebbd..3cdaa0a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,22 +3,43 @@ use specs::prelude::*; use specs::saveload::{ SimpleMarker, SimpleMarkerAllocator }; use bracket_lib::prelude::*; -const DISPLAYWIDTH: i32 = 105; +const DISPLAYWIDTH: i32 = 100; const DISPLAYHEIGHT: i32 = 56; fn main() -> BError { // Embedded resources for use in wasm build - const CURSES_14_16_BYTES: &[u8] = include_bytes!("../resources/curses14x16.png"); - EMBED.lock().add_resource("resources/curses14x16.png".to_string(), CURSES_14_16_BYTES); + { + const WORLD_16_16_BYTES: &[u8] = include_bytes!("../resources/world16x16.png"); + const CURSES_16_16_BYTES: &[u8] = include_bytes!("../resources/curses16x16.png"); + const CURSES_8_16_BYTES: &[u8] = include_bytes!("../resources/curses8x16.png"); + const SINGLE_1_1_BYTES: &[u8] = include_bytes!("../resources/healthbar22x2.png"); + let mut lock = bracket_lib::terminal::EMBED.lock(); + lock.add_resource("resources/world16x16.png".to_string(), WORLD_16_16_BYTES); + lock.add_resource("resources/curses16x16.png".to_string(), CURSES_16_16_BYTES); + lock.add_resource("resources/curses8x16.png".to_string(), CURSES_8_16_BYTES); + lock.add_resource("resources/healthbar22x2.png".to_string(), SINGLE_1_1_BYTES); + } - //link_resource!(CURSES14X16, "../resources/curses_14x16.png"); + let world_sheet = SpriteSheet { + filename: "resources/world16x16.png".to_string(), + sprites: register_spritesheet(16, 16, 19, 16), + backing: None, + }; let mut context = BTermBuilder::new() .with_title("rust-rl") .with_dimensions(DISPLAYWIDTH, DISPLAYHEIGHT) - .with_font("curses14x16.png", 14, 16) - .with_tile_dimensions(14, 16) - .with_simple_console(DISPLAYWIDTH, DISPLAYHEIGHT, "curses14x16.png") + .with_font("curses16x16.png", 16, 16) + .with_font("curses8x16.png", 8, 16) + .with_font("healthbar22x2.png", 1, 1) + .with_tile_dimensions(16, 16) + .with_gutter(2) + .with_sprite_console(DISPLAYWIDTH * 16, DISPLAYHEIGHT * 16, 0) + .with_sprite_sheet(world_sheet) + .with_simple_console_no_bg(DISPLAYWIDTH, DISPLAYHEIGHT, "curses16x16.png") + .with_simple_console_no_bg(DISPLAYWIDTH, DISPLAYHEIGHT, "curses16x16.png") + .with_sparse_console(DISPLAYWIDTH * 2, DISPLAYHEIGHT, "curses8x16.png") + .with_sparse_console(DISPLAYWIDTH * 16, DISPLAYHEIGHT * 16, "healthbar22x2.png") .build()?; if config::CONFIG.visuals.with_scanlines { context.with_post_scanlines(config::CONFIG.visuals.with_screen_burn); @@ -136,3 +157,15 @@ fn main() -> BError { main_loop(context, gs) } + +fn register_spritesheet(width: i32, height: i32, rows: i32, columns: i32) -> Vec { + let mut sprites: Vec = Vec::new(); + for y in 0..rows { + for x in 0..columns { + sprites.push( + Sprite::new(Rect::with_size(x * width + 1, y * height + 1, width, height)) + ); + } + } + sprites +} diff --git a/src/map/dungeon.rs b/src/map/dungeon.rs index 4407efa..ed0bf91 100644 --- a/src/map/dungeon.rs +++ b/src/map/dungeon.rs @@ -112,26 +112,7 @@ fn make_scroll_name(rng: &mut RandomNumberGenerator) -> String { return name; } -const POTION_COLOURS: &[&str] = &[ - "red", - "orange", - "yellow", - "green", - "blue", - "indigo", - "violet", - "black", - "white", - "silver", - "gold", - "rainbow", - "blood", - "purple", - "cyan", - "brown", - "grey", - "octarine", -]; +const POTION_COLOURS: &[&str] = &["blue", "red", "green", "yellow", "black"]; const POTION_ADJECTIVES: &[&str] = &[ "swirling", "viscous", diff --git a/src/map/mod.rs b/src/map/mod.rs index 99a0c6a..9bcacca 100644 --- a/src/map/mod.rs +++ b/src/map/mod.rs @@ -2,7 +2,15 @@ use bracket_lib::prelude::*; use serde::{ Deserialize, Serialize }; use std::collections::{ HashSet, HashMap }; mod tiletype; -pub use tiletype::{ tile_cost, tile_opaque, tile_walkable, TileType, get_dest, Destination }; +pub use tiletype::{ + tile_cost, + tile_opaque, + tile_walkable, + tile_blocks_telepathy, + TileType, + get_dest, + Destination, +}; mod interval_spawning_system; pub use interval_spawning_system::{ maybe_map_message, try_spawn_interval }; pub mod dungeon; diff --git a/src/map/themes.rs b/src/map/themes.rs index 8ddcc2a..bd6fcf3 100644 --- a/src/map/themes.rs +++ b/src/map/themes.rs @@ -5,6 +5,22 @@ use crate::data::ids::*; use bracket_lib::prelude::*; use std::ops::{ Add, Mul }; +pub fn get_sprite_for_id(idx: usize, map: &Map, other_pos: Option) -> (usize, RGBA) { + let x = (idx as i32) % map.width; + let y = (idx as i32) / map.width; + let tile = map.tiles[idx]; + let base = match tile { + TileType::Wall => wall_sprite(tile.sprite(), map, x, y), + _ => tile.sprite(), + }; + let sprite_id = pick_variant(base, tile.variants(), idx, map); + let tint = if !map.visible_tiles[idx] { + RGBA::from_f32(0.75, 0.75, 0.75, 1.0) + } else { + RGBA::named(WHITE) + }; + return (sprite_id, tint); +} /// Gets the renderables for a tile, with darkening/offset/post-processing/etc. Passing a val for "debug" will ignore viewshed. pub fn get_tile_renderables_for_id( idx: usize, @@ -142,6 +158,20 @@ fn is_revealed_and_wall(map: &Map, x: i32, y: i32, debug: Option) -> bool (if debug.is_none() { map.revealed_tiles[idx] } else { true }) } +fn wall_sprite(id: usize, map: &Map, x: i32, y: i32) -> usize { + if y > map.height - (2 as i32) { + return id; + } + if is_revealed_and_wall(map, x, y + 1, None) { + return id + 6; + } + return id; +} + +fn pick_variant(base: usize, variants: usize, idx: usize, map: &Map) -> usize { + return base + ((map.colour_offset[idx].0.0 * (variants as f32)) as usize); +} + fn wall_glyph(map: &Map, x: i32, y: i32, debug: Option) -> FontCharType { if x < 1 || diff --git a/src/map/tiletype.rs b/src/map/tiletype.rs index f451c9b..beb483c 100644 --- a/src/map/tiletype.rs +++ b/src/map/tiletype.rs @@ -1,4 +1,5 @@ use serde::{ Deserialize, Serialize }; +use crate::data::sprites::*; #[derive(PartialEq, Eq, Hash, Copy, Clone, Serialize, Deserialize, Debug)] pub enum TileType { @@ -27,9 +28,64 @@ pub enum TileType { ToOvermap(i32), ToLocal(i32), } + +impl TileType { + pub fn sprite(&self) -> usize { + match self { + TileType::ImpassableMountain => STATUE, + TileType::Wall => WALL_BASE, + TileType::DeepWater => WATER_DEEP, + TileType::Fence => WALL_BASE, + TileType::Bars => WALL_BASE, + TileType::Floor => FLOOR, + TileType::WoodFloor => FLOOR_WOOD, + TileType::Gravel => FLOOR, + TileType::Road => PATH_GRASS, + TileType::Grass => FLOOR_GRASS, + TileType::Foliage => FLOOR_GRASS, + TileType::HeavyFoliage => FLOOR_GRASS, + TileType::Sand => FLOOR, + TileType::ShallowWater => WATER_DEEP, + TileType::Bridge => FLOOR, + TileType::DownStair => STAIR_D, + TileType::UpStair => STAIR_A, + TileType::ToLocal(_) => MUSHROOM, + TileType::ToOvermap(_) => MUSHROOM_ORANGE, + } + } + + pub fn variants(&self) -> usize { + match self { + TileType::ImpassableMountain => 1, + TileType::Wall => 4, + TileType::DeepWater => 2, + TileType::Fence => 1, + TileType::Bars => 1, + TileType::Floor => 6, + TileType::WoodFloor => 3, + TileType::Gravel => 1, + TileType::Road => 4, + TileType::Grass => 6, + TileType::Foliage => 1, + TileType::HeavyFoliage => 1, + TileType::Sand => 1, + TileType::ShallowWater => 2, + TileType::Bridge => 1, + TileType::DownStair => 1, + TileType::UpStair => 1, + TileType::ToLocal(_) => 1, + TileType::ToOvermap(_) => 1, + } + } +} + pub fn tile_walkable(tt: TileType) -> bool { match tt { - TileType::ImpassableMountain | TileType::Wall | TileType::DeepWater | TileType::Fence | TileType::Bars => false, + | TileType::ImpassableMountain + | TileType::Wall + | TileType::DeepWater + | TileType::Fence + | TileType::Bars => false, _ => true, } } @@ -40,6 +96,11 @@ pub fn tile_opaque(tt: TileType) -> bool { _ => false, } } +pub fn tile_blocks_telepathy(tt: TileType) -> bool { + match tt { + _ => false, + } +} pub fn tile_cost(tt: TileType) -> f32 { match tt { TileType::Road => 0.75, diff --git a/src/map_builders/mod.rs b/src/map_builders/mod.rs index 81045c6..7b38efe 100644 --- a/src/map_builders/mod.rs +++ b/src/map_builders/mod.rs @@ -438,21 +438,19 @@ pub fn random_builder( } pub fn level_builder( - new_id: i32, + id: i32, rng: &mut RandomNumberGenerator, width: i32, height: i32, initial_player_level: i32 ) -> BuilderChain { - // TODO: With difficulty and ID/depth decoupled, this can be used for branches later. - let difficulty = new_id; - match new_id { + match id { ID_OVERMAP => overmap_builder(), - ID_TOWN => town_builder(new_id, rng, width, height, 0, initial_player_level), - ID_TOWN2 => forest_builder(new_id, rng, width, height, 1, initial_player_level), + ID_TOWN => town_builder(id, rng, width, height, 0, initial_player_level), + ID_TOWN2 => forest_builder(id, rng, width, height, 1, initial_player_level), ID_TOWN3 => random_builder( - new_id, + id, rng, width, height, @@ -462,25 +460,25 @@ pub fn level_builder( true, BuildType::Room ), - _ if new_id >= ID_INFINITE => + _ if id >= ID_INFINITE => random_builder( - new_id, + id, rng, width, height, - difficulty, - new_id - ID_INFINITE + 1, + 4 + diff(ID_INFINITE, id), + 1 + diff(ID_INFINITE, id), initial_player_level, false, BuildType::Room ), - _ => + _ => // This should be unreachable!() eventually. Right now it's reachable with the debug/cheat menu. It should not be in normal gameplay. random_builder( - new_id, + id, rng, width, height, - difficulty, + 1, 404, initial_player_level, false, @@ -488,3 +486,7 @@ pub fn level_builder( ), } } + +fn diff(branch_id: i32, lvl_id: i32) -> i32 { + return lvl_id - branch_id; +} diff --git a/src/particle_system.rs b/src/particle_system.rs index 69e12b7..b576984 100644 --- a/src/particle_system.rs +++ b/src/particle_system.rs @@ -81,6 +81,7 @@ fn create_delayed_particles(ecs: &mut World, ctx: &BTerm) { .expect("Could not insert position"); renderables .insert(p, Renderable { + sprite: None, // TODO: Particle sprite fg: handled.fg, bg: handled.bg, glyph: handled.glyph, @@ -306,6 +307,7 @@ impl<'a> System<'a> for ParticleSpawnSystem { .expect("Could not insert position"); renderables .insert(p, Renderable { + sprite: None, // TODO: Particle sprite fg: new_particle.fg, bg: new_particle.bg, glyph: new_particle.glyph, diff --git a/src/player.rs b/src/player.rs index dd8ecf3..d91ba3b 100644 --- a/src/player.rs +++ b/src/player.rs @@ -39,6 +39,7 @@ use specs::prelude::*; use std::cmp::{ max, min }; use crate::data::events::*; use crate::data::ids::*; +use crate::gui::with_article; pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState { let mut positions = ecs.write_storage::(); @@ -133,6 +134,7 @@ pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState { let mut renderables = ecs.write_storage::(); let render_data = renderables.get_mut(potential_target).unwrap(); render_data.glyph = to_cp437('+'); // Nethack open door, maybe just use '/' instead. + render_data.sprite = Some(17); // TODO: Enum door_pos = Some(Point::new(pos.x + delta_x, pos.y + delta_y)); } result = RunState::Ticking; @@ -230,6 +232,7 @@ pub fn open(i: i32, j: i32, ecs: &mut World) -> RunState { let mut renderables = ecs.write_storage::(); let render_data = renderables.get_mut(potential_target).unwrap(); render_data.glyph = to_cp437('▓'); // Nethack open door, maybe just use '/' instead. + render_data.sprite = Some(18); // TODO: Enum door_pos = Some(Point::new(pos.x + delta_x, pos.y + delta_y)); } result = RunState::Ticking; @@ -560,11 +563,11 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, ecs: &mut World) -> RunState let mut logger = gamelog::Logger::new().append("You see"); for i in 0..seen_items.len() { if i > 0 && i < seen_items.len() { - logger = logger.append(", a"); + logger = logger.append(", "); } logger = logger .colour(seen_items[i].1) - .append_n(&seen_items[i].0) + .append_n(with_article(&seen_items[i].0)) .colour(WHITE); } logger.period().log(); diff --git a/src/raws/item_structs.rs b/src/raws/item_structs.rs index 897d48d..1bd1a39 100644 --- a/src/raws/item_structs.rs +++ b/src/raws/item_structs.rs @@ -30,6 +30,7 @@ pub struct Equippable { #[derive(Deserialize, Debug)] pub struct Renderable { pub glyph: String, + pub sprite: Option, pub fg: String, pub bg: String, pub order: i32, diff --git a/src/raws/rawmaster.rs b/src/raws/rawmaster.rs index 813dbe2..d15b7c7 100644 --- a/src/raws/rawmaster.rs +++ b/src/raws/rawmaster.rs @@ -691,6 +691,11 @@ fn get_renderable_component( ) -> crate::components::Renderable { crate::components::Renderable { glyph: to_cp437(renderable.glyph.chars().next().unwrap()), + sprite: if let Some(sprite) = &renderable.sprite { + Some(sprite.clone()) + } else { + None + }, fg: RGB::from_hex(&renderable.fg).expect("Invalid RGB"), bg: RGB::from_hex(&renderable.bg).expect("Invalid RGB"), render_order: renderable.order, diff --git a/src/spawner.rs b/src/spawner.rs index 3fa673c..21a68b1 100644 --- a/src/spawner.rs +++ b/src/spawner.rs @@ -54,6 +54,7 @@ pub fn player(ecs: &mut World, player_x: i32, player_y: i32) -> Entity { .with(BlocksTile {}) .with(Renderable { glyph: to_cp437('@'), + sprite: None, // TODO: Player sprite fg: RGB::named(YELLOW), bg: RGB::named(BLACK), render_order: 0, diff --git a/src/states/state.rs b/src/states/state.rs index 0217cca..ed4cd58 100644 --- a/src/states/state.rs +++ b/src/states/state.rs @@ -23,6 +23,7 @@ use crate::camera; use crate::saveload_system; use crate::morgue; use crate::damage_system; +use crate::data::prelude::*; pub struct State { pub ecs: World, @@ -164,6 +165,15 @@ impl GameState for State { new_runstate = *runstate; } // Clear screen + ctx.set_active_console(0); + ctx.cls(); + ctx.set_active_console(HP_BAR_LAYER); + ctx.cls(); + ctx.set_active_console(TEXT_LAYER); + ctx.cls(); + ctx.set_active_console(ENTITY_LAYER); + ctx.cls(); + ctx.set_active_console(TILE_LAYER); ctx.cls(); particle_system::particle_ticker(&mut self.ecs, ctx); @@ -559,6 +569,15 @@ impl GameState for State { new_runstate = self.mapgen_next_state.unwrap(); } if self.mapgen_history.len() != 0 { + ctx.set_active_console(0); + ctx.cls(); + ctx.set_active_console(HP_BAR_LAYER); + ctx.cls(); + ctx.set_active_console(TEXT_LAYER); + ctx.cls(); + ctx.set_active_console(ENTITY_LAYER); + ctx.cls(); + ctx.set_active_console(TILE_LAYER); ctx.cls(); camera::render_debug_map(&self.mapgen_history[self.mapgen_index], ctx); diff --git a/src/visibility_system.rs b/src/visibility_system.rs index e53b0e1..521eecd 100644 --- a/src/visibility_system.rs +++ b/src/visibility_system.rs @@ -11,6 +11,7 @@ use super::{ Viewshed, Renderable, gui::renderable_colour, + tile_blocks_telepathy, }; use bracket_lib::prelude::*; use bracket_lib::pathfinding::FieldOfViewAlg::SymmetricShadowcasting; @@ -120,7 +121,7 @@ impl<'a> System<'a> for VisibilitySystem { if let Some(_is_blind) = blind_entities.get(ent) { range *= BLIND_TELEPATHY_RANGE_MULTIPLIER; } - telepath.telepath_tiles = fast_fov(pos.x, pos.y, range); + telepath.telepath_tiles = fast_fov(pos.x, pos.y, range, &map); telepath.telepath_tiles.retain( |p| p.x >= 0 && p.x < map.width && p.y >= 0 && p.y < map.height ); @@ -141,7 +142,7 @@ impl<'a> System<'a> for VisibilitySystem { } } -pub fn fast_fov(p_x: i32, p_y: i32, r: i32) -> Vec { +pub fn fast_fov(p_x: i32, p_y: i32, r: i32, map: &WriteExpect) -> Vec { let mut visible_tiles: Vec = Vec::new(); let mut i = 0; @@ -152,7 +153,17 @@ pub fn fast_fov(p_x: i32, p_y: i32, r: i32) -> Vec { let mut ox: f32 = (p_x as f32) + (0.5 as f32); let mut oy: f32 = (p_y as f32) + (0.5 as f32); for _i in 0..r { - visible_tiles.push(Point::new(ox as i32, oy as i32)); + let (ox_i32, oy_i32) = (ox as i32, oy as i32); + visible_tiles.push(Point::new(ox_i32, oy_i32)); + if + ox_i32 >= 0 && + ox_i32 < map.width && + oy_i32 >= 0 && + oy_i32 < map.height && + tile_blocks_telepathy(map.tiles[map.xy_idx(ox_i32, oy_i32)]) + { + break; + } ox += x; oy += y; } diff --git a/wasm/rust-rl.js b/wasm/rust-rl.js index ffbe20e..7036263 100644 --- a/wasm/rust-rl.js +++ b/wasm/rust-rl.js @@ -212,11 +212,11 @@ function makeMutClosure(arg0, arg1, dtor, f) { return real; } function __wbg_adapter_20(arg0, arg1) { - wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb6c6b1cd103d974c(arg0, arg1); + wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h66b665bcfa5ccc10(arg0, arg1); } function __wbg_adapter_23(arg0, arg1, arg2) { - wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h02b9f16709be0849(arg0, arg1, addHeapObject(arg2)); + wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h7f980deb71f217f3(arg0, arg1, addHeapObject(arg2)); } function handleError(f, args) { @@ -817,16 +817,16 @@ function __wbg_get_imports() { const ret = wasm.memory; return addHeapObject(ret); }; - imports.wbg.__wbindgen_closure_wrapper258 = function(arg0, arg1, arg2) { - const ret = makeMutClosure(arg0, arg1, 15, __wbg_adapter_20); + imports.wbg.__wbindgen_closure_wrapper257 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 14, __wbg_adapter_20); return addHeapObject(ret); }; - imports.wbg.__wbindgen_closure_wrapper2954 = function(arg0, arg1, arg2) { - const ret = makeMutClosure(arg0, arg1, 696, __wbg_adapter_23); + imports.wbg.__wbindgen_closure_wrapper2960 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 698, __wbg_adapter_23); return addHeapObject(ret); }; - imports.wbg.__wbindgen_closure_wrapper2956 = function(arg0, arg1, arg2) { - const ret = makeMutClosure(arg0, arg1, 696, __wbg_adapter_23); + imports.wbg.__wbindgen_closure_wrapper2962 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 698, __wbg_adapter_23); return addHeapObject(ret); }; diff --git a/wasm/rust-rl_bg.wasm b/wasm/rust-rl_bg.wasm index f48ccb7..79ebb75 100644 Binary files a/wasm/rust-rl_bg.wasm and b/wasm/rust-rl_bg.wasm differ diff --git a/web/rust-rl.js b/web/rust-rl.js new file mode 100644 index 0000000..7036263 --- /dev/null +++ b/web/rust-rl.js @@ -0,0 +1,887 @@ +let wasm_bindgen; +(function() { + const __exports = {}; + let script_src; + if (typeof document !== 'undefined' && document.currentScript !== null) { + script_src = new URL(document.currentScript.src, location.href).toString(); + } + let wasm = undefined; + + const heap = new Array(128).fill(undefined); + + heap.push(undefined, null, true, false); + +function getObject(idx) { return heap[idx]; } + +let heap_next = heap.length; + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + +let WASM_VECTOR_LEN = 0; + +let cachedUint8Memory0 = null; + +function getUint8Memory0() { + if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) { + cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8Memory0; +} + +const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8Memory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8Memory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +let cachedInt32Memory0 = null; + +function getInt32Memory0() { + if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) { + cachedInt32Memory0 = new Int32Array(wasm.memory.buffer); + } + return cachedInt32Memory0; +} + +function debugString(val) { + // primitive types + const type = typeof val; + if (type == 'number' || type == 'boolean' || val == null) { + return `${val}`; + } + if (type == 'string') { + return `"${val}"`; + } + if (type == 'symbol') { + const description = val.description; + if (description == null) { + return 'Symbol'; + } else { + return `Symbol(${description})`; + } + } + if (type == 'function') { + const name = val.name; + if (typeof name == 'string' && name.length > 0) { + return `Function(${name})`; + } else { + return 'Function'; + } + } + // objects + if (Array.isArray(val)) { + const length = val.length; + let debug = '['; + if (length > 0) { + debug += debugString(val[0]); + } + for(let i = 1; i < length; i++) { + debug += ', ' + debugString(val[i]); + } + debug += ']'; + return debug; + } + // Test for built-in + const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val)); + let className; + if (builtInMatches.length > 1) { + className = builtInMatches[1]; + } else { + // Failed to match the standard '[object ClassName]' + return toString.call(val); + } + if (className == 'Object') { + // we're a user defined class or Object + // JSON.stringify avoids problems with cycles, and is generally much + // easier than looping through ownProperties of `val`. + try { + return 'Object(' + JSON.stringify(val) + ')'; + } catch (_) { + return 'Object'; + } + } + // errors + if (val instanceof Error) { + return `${val.name}: ${val.message}\n${val.stack}`; + } + // TODO we could test for more things here, like `Set`s and `Map`s. + return className; +} + +const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + +if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); +} + +function makeMutClosure(arg0, arg1, dtor, f) { + const state = { a: arg0, b: arg1, cnt: 1, dtor }; + const real = (...args) => { + // First up with a closure we increment the internal reference + // count. This ensures that the Rust closure environment won't + // be deallocated while we're invoking it. + state.cnt++; + const a = state.a; + state.a = 0; + try { + return f(a, state.b, ...args); + } finally { + if (--state.cnt === 0) { + wasm.__wbindgen_export_2.get(state.dtor)(a, state.b); + + } else { + state.a = a; + } + } + }; + real.original = state; + + return real; +} +function __wbg_adapter_20(arg0, arg1) { + wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h66b665bcfa5ccc10(arg0, arg1); +} + +function __wbg_adapter_23(arg0, arg1, arg2) { + wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h7f980deb71f217f3(arg0, arg1, addHeapObject(arg2)); +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + wasm.__wbindgen_exn_store(addHeapObject(e)); + } +} + +function getArrayU8FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len); +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + + } else { + return instance; + } + } +} + +function __wbg_get_imports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbindgen_cb_drop = function(arg0) { + const obj = takeObject(arg0).original; + if (obj.cnt-- == 1) { + obj.a = 0; + return true; + } + const ret = false; + return ret; + }; + imports.wbg.__wbindgen_object_drop_ref = function(arg0) { + takeObject(arg0); + }; + imports.wbg.__wbg_log_0e24d345b14995ec = function(arg0, arg1) { + console.log(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbindgen_object_clone_ref = function(arg0) { + const ret = getObject(arg0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_new_abda76e883ba8a5f = function() { + const ret = new Error(); + return addHeapObject(ret); + }; + imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) { + const ret = getObject(arg1).stack; + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; + }; + imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) { + let deferred0_0; + let deferred0_1; + try { + deferred0_0 = arg0; + deferred0_1 = arg1; + console.error(getStringFromWasm0(arg0, arg1)); + } finally { + wasm.__wbindgen_free(deferred0_0, deferred0_1, 1); + } + }; + imports.wbg.__wbindgen_string_get = function(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; + }; + imports.wbg.__wbindgen_boolean_get = function(arg0) { + const v = getObject(arg0); + const ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2; + return ret; + }; + imports.wbg.__wbg_instanceof_WebGl2RenderingContext_f921526c513bf717 = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof WebGL2RenderingContext; + } catch { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_bindVertexArray_8863a216d7b0a339 = function(arg0, arg1) { + getObject(arg0).bindVertexArray(getObject(arg1)); + }; + imports.wbg.__wbg_bufferData_21334671c4ba6004 = function(arg0, arg1, arg2, arg3) { + getObject(arg0).bufferData(arg1 >>> 0, getObject(arg2), arg3 >>> 0); + }; + imports.wbg.__wbg_createVertexArray_51d51e1e1e13e9f6 = function(arg0) { + const ret = getObject(arg0).createVertexArray(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_texImage2D_07240affd06971e9 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) { + getObject(arg0).texImage2D(arg1 >>> 0, arg2, arg3, arg4, arg5, arg6, arg7 >>> 0, arg8 >>> 0, getObject(arg9)); + }, arguments) }; + imports.wbg.__wbg_attachShader_47256b6b3d42a22e = function(arg0, arg1, arg2) { + getObject(arg0).attachShader(getObject(arg1), getObject(arg2)); + }; + imports.wbg.__wbg_bindBuffer_24f6010e273fa400 = function(arg0, arg1, arg2) { + getObject(arg0).bindBuffer(arg1 >>> 0, getObject(arg2)); + }; + imports.wbg.__wbg_bindFramebuffer_a9573e340dab20fe = function(arg0, arg1, arg2) { + getObject(arg0).bindFramebuffer(arg1 >>> 0, getObject(arg2)); + }; + imports.wbg.__wbg_bindTexture_92d6d7f8bff9531e = function(arg0, arg1, arg2) { + getObject(arg0).bindTexture(arg1 >>> 0, getObject(arg2)); + }; + imports.wbg.__wbg_blendFunc_533de6de45b80a09 = function(arg0, arg1, arg2) { + getObject(arg0).blendFunc(arg1 >>> 0, arg2 >>> 0); + }; + imports.wbg.__wbg_clear_2db2efe323bfdf68 = function(arg0, arg1) { + getObject(arg0).clear(arg1 >>> 0); + }; + imports.wbg.__wbg_clearColor_7a7d04702f7e38e5 = function(arg0, arg1, arg2, arg3, arg4) { + getObject(arg0).clearColor(arg1, arg2, arg3, arg4); + }; + imports.wbg.__wbg_compileShader_6bf78b425d5c98e1 = function(arg0, arg1) { + getObject(arg0).compileShader(getObject(arg1)); + }; + imports.wbg.__wbg_createBuffer_323425af422748ac = function(arg0) { + const ret = getObject(arg0).createBuffer(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_createFramebuffer_1684a99697ac9563 = function(arg0) { + const ret = getObject(arg0).createFramebuffer(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_createProgram_4eaf3b97b5747a62 = function(arg0) { + const ret = getObject(arg0).createProgram(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_createShader_429776c9dd6fb87b = function(arg0, arg1) { + const ret = getObject(arg0).createShader(arg1 >>> 0); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_createTexture_1bf4d6fec570124b = function(arg0) { + const ret = getObject(arg0).createTexture(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_disable_e02106ca6c7002d6 = function(arg0, arg1) { + getObject(arg0).disable(arg1 >>> 0); + }; + imports.wbg.__wbg_drawArrays_c91ce3f736bf1f2a = function(arg0, arg1, arg2, arg3) { + getObject(arg0).drawArrays(arg1 >>> 0, arg2, arg3); + }; + imports.wbg.__wbg_drawElements_a9529eefaf2008bd = function(arg0, arg1, arg2, arg3, arg4) { + getObject(arg0).drawElements(arg1 >>> 0, arg2, arg3 >>> 0, arg4); + }; + imports.wbg.__wbg_enable_195891416c520019 = function(arg0, arg1) { + getObject(arg0).enable(arg1 >>> 0); + }; + imports.wbg.__wbg_enableVertexAttribArray_8804480c2ea0bb72 = function(arg0, arg1) { + getObject(arg0).enableVertexAttribArray(arg1 >>> 0); + }; + imports.wbg.__wbg_framebufferTexture2D_e88fcbd7f8523bb8 = function(arg0, arg1, arg2, arg3, arg4, arg5) { + getObject(arg0).framebufferTexture2D(arg1 >>> 0, arg2 >>> 0, arg3 >>> 0, getObject(arg4), arg5); + }; + imports.wbg.__wbg_getError_7191ad6ea53607fe = function(arg0) { + const ret = getObject(arg0).getError(); + return ret; + }; + imports.wbg.__wbg_getExtension_77909f6d51d49d4d = function() { return handleError(function (arg0, arg1, arg2) { + const ret = getObject(arg0).getExtension(getStringFromWasm0(arg1, arg2)); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_getParameter_55b36a787dbbfb74 = function() { return handleError(function (arg0, arg1) { + const ret = getObject(arg0).getParameter(arg1 >>> 0); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_getProgramInfoLog_b81bc53188e286fa = function(arg0, arg1, arg2) { + const ret = getObject(arg1).getProgramInfoLog(getObject(arg2)); + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; + }; + imports.wbg.__wbg_getProgramParameter_35522a0bfdfaad27 = function(arg0, arg1, arg2) { + const ret = getObject(arg0).getProgramParameter(getObject(arg1), arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_getShaderInfoLog_968b93e75477d725 = function(arg0, arg1, arg2) { + const ret = getObject(arg1).getShaderInfoLog(getObject(arg2)); + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; + }; + imports.wbg.__wbg_getShaderParameter_ac2727ae4fe7648e = function(arg0, arg1, arg2) { + const ret = getObject(arg0).getShaderParameter(getObject(arg1), arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_getSupportedExtensions_fafc31aab913037d = function(arg0) { + const ret = getObject(arg0).getSupportedExtensions(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_getUniformLocation_9f6eb60c560a347b = function(arg0, arg1, arg2, arg3) { + const ret = getObject(arg0).getUniformLocation(getObject(arg1), getStringFromWasm0(arg2, arg3)); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_linkProgram_33998194075d71fb = function(arg0, arg1) { + getObject(arg0).linkProgram(getObject(arg1)); + }; + imports.wbg.__wbg_shaderSource_1cb7c64dc7d1a500 = function(arg0, arg1, arg2, arg3) { + getObject(arg0).shaderSource(getObject(arg1), getStringFromWasm0(arg2, arg3)); + }; + imports.wbg.__wbg_texParameteri_85dad939f62a15aa = function(arg0, arg1, arg2, arg3) { + getObject(arg0).texParameteri(arg1 >>> 0, arg2 >>> 0, arg3); + }; + imports.wbg.__wbg_uniform1i_d2e61a6a43889648 = function(arg0, arg1, arg2) { + getObject(arg0).uniform1i(getObject(arg1), arg2); + }; + imports.wbg.__wbg_uniform3f_8364a0959b6c1570 = function(arg0, arg1, arg2, arg3, arg4) { + getObject(arg0).uniform3f(getObject(arg1), arg2, arg3, arg4); + }; + imports.wbg.__wbg_useProgram_3683cf6f60939dcd = function(arg0, arg1) { + getObject(arg0).useProgram(getObject(arg1)); + }; + imports.wbg.__wbg_vertexAttribPointer_316ffe2f0458fde7 = function(arg0, arg1, arg2, arg3, arg4, arg5, arg6) { + getObject(arg0).vertexAttribPointer(arg1 >>> 0, arg2, arg3 >>> 0, arg4 !== 0, arg5, arg6); + }; + imports.wbg.__wbg_getElementById_cc0e0d931b0d9a28 = function(arg0, arg1, arg2) { + const ret = getObject(arg0).getElementById(getStringFromWasm0(arg1, arg2)); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_instanceof_HtmlCanvasElement_da5f9efa0688cf6d = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof HTMLCanvasElement; + } catch { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_setwidth_a667a942dba6656e = function(arg0, arg1) { + getObject(arg0).width = arg1 >>> 0; + }; + imports.wbg.__wbg_setheight_a747d440760fe5aa = function(arg0, arg1) { + getObject(arg0).height = arg1 >>> 0; + }; + imports.wbg.__wbg_getContext_7c5944ea807bf5d3 = function() { return handleError(function (arg0, arg1, arg2) { + const ret = getObject(arg0).getContext(getStringFromWasm0(arg1, arg2)); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_offsetX_5a58f16f6c3a41b6 = function(arg0) { + const ret = getObject(arg0).offsetX; + return ret; + }; + imports.wbg.__wbg_offsetY_c45b4956f6429a95 = function(arg0) { + const ret = getObject(arg0).offsetY; + return ret; + }; + imports.wbg.__wbg_now_0cfdc90c97d0c24b = function(arg0) { + const ret = getObject(arg0).now(); + return ret; + }; + imports.wbg.__wbg_instanceof_Window_9029196b662bc42a = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof Window; + } catch { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_charCode_75cea1a3a6d66388 = function(arg0) { + const ret = getObject(arg0).charCode; + return ret; + }; + imports.wbg.__wbg_keyCode_dfa86be31f5ef90c = function(arg0) { + const ret = getObject(arg0).keyCode; + return ret; + }; + imports.wbg.__wbg_code_96d6322b968b2d17 = function(arg0, arg1) { + const ret = getObject(arg1).code; + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; + }; + imports.wbg.__wbg_getModifierState_5102ee8843516d2f = function(arg0, arg1, arg2) { + const ret = getObject(arg0).getModifierState(getStringFromWasm0(arg1, arg2)); + return ret; + }; + imports.wbg.__wbg_document_f7ace2b956f30a4f = function(arg0) { + const ret = getObject(arg0).document; + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_performance_2c295061c8b01e0b = function(arg0) { + const ret = getObject(arg0).performance; + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_setonkeydown_933cca3c9000a932 = function(arg0, arg1) { + getObject(arg0).onkeydown = getObject(arg1); + }; + imports.wbg.__wbg_setonkeyup_0dfb23e81d0afdde = function(arg0, arg1) { + getObject(arg0).onkeyup = getObject(arg1); + }; + imports.wbg.__wbg_requestAnimationFrame_d082200514b6674d = function() { return handleError(function (arg0, arg1) { + const ret = getObject(arg0).requestAnimationFrame(getObject(arg1)); + return ret; + }, arguments) }; + imports.wbg.__wbg_setonmousedown_4f38d9c057bbfcbd = function(arg0, arg1) { + getObject(arg0).onmousedown = getObject(arg1); + }; + imports.wbg.__wbg_setonmousemove_c0b17753786f3544 = function(arg0, arg1) { + getObject(arg0).onmousemove = getObject(arg1); + }; + imports.wbg.__wbg_setonmouseup_4b447fa380e33802 = function(arg0, arg1) { + getObject(arg0).onmouseup = getObject(arg1); + }; + imports.wbg.__wbg_bufferData_a11a9f65f31e7256 = function(arg0, arg1, arg2, arg3) { + getObject(arg0).bufferData(arg1 >>> 0, getObject(arg2), arg3 >>> 0); + }; + imports.wbg.__wbg_texImage2D_6175916e58c59bc7 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) { + getObject(arg0).texImage2D(arg1 >>> 0, arg2, arg3, arg4, arg5, arg6, arg7 >>> 0, arg8 >>> 0, getObject(arg9)); + }, arguments) }; + imports.wbg.__wbg_attachShader_b65b695055670cb5 = function(arg0, arg1, arg2) { + getObject(arg0).attachShader(getObject(arg1), getObject(arg2)); + }; + imports.wbg.__wbg_bindBuffer_313561e5bc0e533f = function(arg0, arg1, arg2) { + getObject(arg0).bindBuffer(arg1 >>> 0, getObject(arg2)); + }; + imports.wbg.__wbg_bindFramebuffer_56bf6536a4ced0ec = function(arg0, arg1, arg2) { + getObject(arg0).bindFramebuffer(arg1 >>> 0, getObject(arg2)); + }; + imports.wbg.__wbg_bindTexture_9cb5c770d1ba2cca = function(arg0, arg1, arg2) { + getObject(arg0).bindTexture(arg1 >>> 0, getObject(arg2)); + }; + imports.wbg.__wbg_blendFunc_fbe9d3a688fe71c3 = function(arg0, arg1, arg2) { + getObject(arg0).blendFunc(arg1 >>> 0, arg2 >>> 0); + }; + imports.wbg.__wbg_clear_2ccea1f65b510c97 = function(arg0, arg1) { + getObject(arg0).clear(arg1 >>> 0); + }; + imports.wbg.__wbg_clearColor_de587608b28bc7ed = function(arg0, arg1, arg2, arg3, arg4) { + getObject(arg0).clearColor(arg1, arg2, arg3, arg4); + }; + imports.wbg.__wbg_compileShader_d88d0a8cd9b72b4d = function(arg0, arg1) { + getObject(arg0).compileShader(getObject(arg1)); + }; + imports.wbg.__wbg_createBuffer_59051f4461e7c5e2 = function(arg0) { + const ret = getObject(arg0).createBuffer(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_createFramebuffer_223c1212ad76affc = function(arg0) { + const ret = getObject(arg0).createFramebuffer(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_createProgram_88dbe21c0b682e1a = function(arg0) { + const ret = getObject(arg0).createProgram(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_createShader_9d7d388633caad18 = function(arg0, arg1) { + const ret = getObject(arg0).createShader(arg1 >>> 0); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_createTexture_9d0bb4d741b8ad76 = function(arg0) { + const ret = getObject(arg0).createTexture(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_disable_5cf2070641fa2ed7 = function(arg0, arg1) { + getObject(arg0).disable(arg1 >>> 0); + }; + imports.wbg.__wbg_drawArrays_d5c7dc2b2376c85a = function(arg0, arg1, arg2, arg3) { + getObject(arg0).drawArrays(arg1 >>> 0, arg2, arg3); + }; + imports.wbg.__wbg_drawElements_3316ee0cd1117c2a = function(arg0, arg1, arg2, arg3, arg4) { + getObject(arg0).drawElements(arg1 >>> 0, arg2, arg3 >>> 0, arg4); + }; + imports.wbg.__wbg_enable_8965e69c596f0a94 = function(arg0, arg1) { + getObject(arg0).enable(arg1 >>> 0); + }; + imports.wbg.__wbg_enableVertexAttribArray_2b0475db43533cf2 = function(arg0, arg1) { + getObject(arg0).enableVertexAttribArray(arg1 >>> 0); + }; + imports.wbg.__wbg_framebufferTexture2D_953e69a8bec22fa9 = function(arg0, arg1, arg2, arg3, arg4, arg5) { + getObject(arg0).framebufferTexture2D(arg1 >>> 0, arg2 >>> 0, arg3 >>> 0, getObject(arg4), arg5); + }; + imports.wbg.__wbg_getError_1e5ec1ec9e58b323 = function(arg0) { + const ret = getObject(arg0).getError(); + return ret; + }; + imports.wbg.__wbg_getProgramInfoLog_0b7af4ad85fa52a4 = function(arg0, arg1, arg2) { + const ret = getObject(arg1).getProgramInfoLog(getObject(arg2)); + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; + }; + imports.wbg.__wbg_getProgramParameter_2a3735278367f8bc = function(arg0, arg1, arg2) { + const ret = getObject(arg0).getProgramParameter(getObject(arg1), arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_getShaderInfoLog_979aafa403ffb252 = function(arg0, arg1, arg2) { + const ret = getObject(arg1).getShaderInfoLog(getObject(arg2)); + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; + }; + imports.wbg.__wbg_getShaderParameter_e8054f1d9026fb70 = function(arg0, arg1, arg2) { + const ret = getObject(arg0).getShaderParameter(getObject(arg1), arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_getUniformLocation_688976233799a45a = function(arg0, arg1, arg2, arg3) { + const ret = getObject(arg0).getUniformLocation(getObject(arg1), getStringFromWasm0(arg2, arg3)); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_linkProgram_9a2d12d120d99917 = function(arg0, arg1) { + getObject(arg0).linkProgram(getObject(arg1)); + }; + imports.wbg.__wbg_shaderSource_f435f9b74440bb54 = function(arg0, arg1, arg2, arg3) { + getObject(arg0).shaderSource(getObject(arg1), getStringFromWasm0(arg2, arg3)); + }; + imports.wbg.__wbg_texParameteri_1f17358e51eb8069 = function(arg0, arg1, arg2, arg3) { + getObject(arg0).texParameteri(arg1 >>> 0, arg2 >>> 0, arg3); + }; + imports.wbg.__wbg_uniform1i_9f94ef0ba6b3cc66 = function(arg0, arg1, arg2) { + getObject(arg0).uniform1i(getObject(arg1), arg2); + }; + imports.wbg.__wbg_uniform3f_c682f4b32f713d1a = function(arg0, arg1, arg2, arg3, arg4) { + getObject(arg0).uniform3f(getObject(arg1), arg2, arg3, arg4); + }; + imports.wbg.__wbg_useProgram_019eb6df066fabf5 = function(arg0, arg1) { + getObject(arg0).useProgram(getObject(arg1)); + }; + imports.wbg.__wbg_vertexAttribPointer_ca11984ee8843c0a = function(arg0, arg1, arg2, arg3, arg4, arg5, arg6) { + getObject(arg0).vertexAttribPointer(arg1 >>> 0, arg2, arg3 >>> 0, arg4 !== 0, arg5, arg6); + }; + imports.wbg.__wbg_bindVertexArrayOES_b7d9da7e073aa6b5 = function(arg0, arg1) { + getObject(arg0).bindVertexArrayOES(getObject(arg1)); + }; + imports.wbg.__wbg_createVertexArrayOES_6a3c3a5a68201f8f = function(arg0) { + const ret = getObject(arg0).createVertexArrayOES(); + return isLikeNone(ret) ? 0 : addHeapObject(ret); + }; + imports.wbg.__wbg_self_1c2814d86e6e51e3 = function() { return handleError(function () { + const ret = self.self; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_crypto_70532d614bc7e028 = function(arg0) { + const ret = getObject(arg0).crypto; + return addHeapObject(ret); + }; + imports.wbg.__wbg_msCrypto_4e9b4dd0e1abade6 = function(arg0) { + const ret = getObject(arg0).msCrypto; + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_is_undefined = function(arg0) { + const ret = getObject(arg0) === undefined; + return ret; + }; + imports.wbg.__wbg_static_accessor_MODULE_7781e47b50010688 = function() { + const ret = module; + return addHeapObject(ret); + }; + imports.wbg.__wbg_require_9ace3ae680954e98 = function() { return handleError(function (arg0, arg1, arg2) { + const ret = getObject(arg0).require(getStringFromWasm0(arg1, arg2)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_getRandomValues_f6c9b08ef5448767 = function() { return handleError(function (arg0, arg1) { + getObject(arg0).getRandomValues(getObject(arg1)); + }, arguments) }; + imports.wbg.__wbg_randomFillSync_bf67eeddb65b346b = function() { return handleError(function (arg0, arg1, arg2) { + getObject(arg0).randomFillSync(getArrayU8FromWasm0(arg1, arg2)); + }, arguments) }; + imports.wbg.__wbg_get_44be0491f933a435 = function(arg0, arg1) { + const ret = getObject(arg0)[arg1 >>> 0]; + return addHeapObject(ret); + }; + imports.wbg.__wbg_length_fff51ee6522a1a18 = function(arg0) { + const ret = getObject(arg0).length; + return ret; + }; + imports.wbg.__wbg_newnoargs_581967eacc0e2604 = function(arg0, arg1) { + const ret = new Function(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_call_cb65541d95d71282 = function() { return handleError(function (arg0, arg1) { + const ret = getObject(arg0).call(getObject(arg1)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_self_1ff1d729e9aae938 = function() { return handleError(function () { + const ret = self.self; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_window_5f4faef6c12b79ec = function() { return handleError(function () { + const ret = window.window; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_globalThis_1d39714405582d3c = function() { return handleError(function () { + const ret = globalThis.globalThis; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_global_651f05c6a0944d1c = function() { return handleError(function () { + const ret = global.global; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_now_9c5990bda04c7e53 = function() { + const ret = Date.now(); + return ret; + }; + imports.wbg.__wbg_buffer_085ec1f694018c4f = function(arg0) { + const ret = getObject(arg0).buffer; + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_828b952f0e692245 = function(arg0, arg1, arg2) { + const ret = new Int8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_735ed5ea2ae07fe9 = function(arg0, arg1, arg2) { + const ret = new Int16Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_9f43b22ab631d1d6 = function(arg0, arg1, arg2) { + const ret = new Int32Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_6da8e527659b86aa = function(arg0, arg1, arg2) { + const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_new_8125e318e6245eed = function(arg0) { + const ret = new Uint8Array(getObject(arg0)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_set_5cf90238115182c3 = function(arg0, arg1, arg2) { + getObject(arg0).set(getObject(arg1), arg2 >>> 0); + }; + imports.wbg.__wbg_length_72e2208bbc0efc61 = function(arg0) { + const ret = getObject(arg0).length; + return ret; + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_31ff1024ef0c63c7 = function(arg0, arg1, arg2) { + const ret = new Uint16Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_6df0e8c3efd2a5d3 = function(arg0, arg1, arg2) { + const ret = new Uint32Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_69193e31c844b792 = function(arg0, arg1, arg2) { + const ret = new Float32Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_newwithlength_e5d69174d6984cd7 = function(arg0) { + const ret = new Uint8Array(arg0 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbg_subarray_13db269f57aa838d = function(arg0, arg1, arg2) { + const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_debug_string = function(arg0, arg1) { + const ret = debugString(getObject(arg1)); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getInt32Memory0()[arg0 / 4 + 1] = len1; + getInt32Memory0()[arg0 / 4 + 0] = ptr1; + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbindgen_memory = function() { + const ret = wasm.memory; + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_closure_wrapper257 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 14, __wbg_adapter_20); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_closure_wrapper2960 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 698, __wbg_adapter_23); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_closure_wrapper2962 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 698, __wbg_adapter_23); + return addHeapObject(ret); + }; + + return imports; +} + +function __wbg_init_memory(imports, maybe_memory) { + +} + +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + __wbg_init.__wbindgen_wasm_module = module; + cachedInt32Memory0 = null; + cachedUint8Memory0 = null; + + wasm.__wbindgen_start(); + return wasm; +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + const imports = __wbg_get_imports(); + + __wbg_init_memory(imports); + + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + + const instance = new WebAssembly.Instance(module, imports); + + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(input) { + if (wasm !== undefined) return wasm; + + if (typeof input === 'undefined' && script_src !== 'undefined') { + input = script_src.replace(/\.js$/, '_bg.wasm'); + } + const imports = __wbg_get_imports(); + + if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) { + input = fetch(input); + } + + __wbg_init_memory(imports); + + const { instance, module } = await __wbg_load(await input, imports); + + return __wbg_finalize_init(instance, module); +} + +wasm_bindgen = Object.assign(__wbg_init, { initSync }, __exports); + +})(); diff --git a/web/rust-rl_bg.wasm b/web/rust-rl_bg.wasm new file mode 100644 index 0000000..79ebb75 Binary files /dev/null and b/web/rust-rl_bg.wasm differ