camera rendering, and breaking things temporarily
This commit is contained in:
parent
1299524c91
commit
d9489e7ddc
6 changed files with 202 additions and 217 deletions
|
|
@ -7,7 +7,20 @@ use super::data::prelude::*;
|
|||
|
||||
const SHOW_BOUNDARIES: bool = false;
|
||||
|
||||
pub fn get_screen_bounds(ecs: &World) -> (i32, i32, i32, i32, i32, i32) {
|
||||
pub fn get_offset() -> (i32, i32) {
|
||||
return (1, 10);
|
||||
}
|
||||
|
||||
pub struct ScreenBounds {
|
||||
pub min_x: i32,
|
||||
pub max_x: i32,
|
||||
pub min_y: i32,
|
||||
pub max_y: i32,
|
||||
pub x_offset: i32,
|
||||
pub y_offset: i32,
|
||||
}
|
||||
|
||||
pub fn get_screen_bounds(ecs: &World) -> ScreenBounds {
|
||||
let player_pos = ecs.fetch::<Point>();
|
||||
let map = ecs.fetch::<Map>();
|
||||
let (x_chars, y_chars, mut x_offset, mut y_offset) = (VIEWPORT_W, VIEWPORT_H, 1, 10);
|
||||
|
|
@ -30,7 +43,11 @@ pub fn get_screen_bounds(ecs: &World) -> (i32, i32, i32, i32, i32, i32) {
|
|||
let max_x = min_x + (x_chars as i32);
|
||||
let max_y = min_y + (y_chars as i32);
|
||||
|
||||
(min_x, max_x, min_y, max_y, x_offset, y_offset)
|
||||
ScreenBounds { min_x, max_x, min_y, max_y, x_offset, y_offset }
|
||||
}
|
||||
|
||||
pub fn in_bounds(x: i32, y: i32, upper_x: i32, upper_y: i32) -> bool {
|
||||
x >= 0 && x < upper_x && y >= 0 && y < upper_y
|
||||
}
|
||||
|
||||
pub fn render_camera(ecs: &World, ctx: &mut BTerm) {
|
||||
|
|
@ -64,7 +81,7 @@ pub fn render_camera(ecs: &World, ctx: &mut BTerm) {
|
|||
Rect::with_size(x * 16 + x_offset * 16, y * 16 + y_offset * 16, 16, 16),
|
||||
0,
|
||||
tint,
|
||||
id
|
||||
0 // Ya
|
||||
);
|
||||
ctx.set_active_console(TILE_LAYER);
|
||||
}
|
||||
|
|
|
|||
52
src/main.rs
52
src/main.rs
|
|
@ -146,18 +146,60 @@ fn setup(gfx: &mut Graphics) -> State {
|
|||
|
||||
gs
|
||||
}
|
||||
const ASCII_MODE: bool = false; // Change this to config setting
|
||||
const SHOW_BOUNDARIES: bool = false; // Config setting
|
||||
use notan::draw::Draw;
|
||||
fn draw_camera(ecs: &World, draw: &mut Draw, atlas: &HashMap<String, Texture>) {
|
||||
let map = ecs.fetch::<Map>();
|
||||
let bounds = crate::camera::get_screen_bounds(ecs);
|
||||
render_map_in_view(&*map, ecs, draw, bounds);
|
||||
}
|
||||
|
||||
use crate::camera::ScreenBounds;
|
||||
fn render_map_in_view(map: &Map, ecs: &World, draw: &mut Draw, bounds: ScreenBounds) {
|
||||
for tile_y in bounds.min_y..bounds.max_y {
|
||||
for tile_x in bounds.min_x..bounds.max_x {
|
||||
if crate::camera::in_bounds(tile_x, tile_y, map.width, map.height) {
|
||||
let idx = map.xy_idx(tile_x, tile_y);
|
||||
if map.revealed_tiles[idx] {
|
||||
if ASCII_MODE {
|
||||
let (glyph, fg, bg) = crate::map::themes::get_tile_renderables_for_id(
|
||||
idx,
|
||||
&*map,
|
||||
Some(*ecs.fetch::<Point>()),
|
||||
None
|
||||
);
|
||||
// TODO: Draw ASCII
|
||||
} else {
|
||||
let (id, tint) = crate::map::themes::get_sprite_for_id(
|
||||
idx,
|
||||
&*map,
|
||||
Some(*ecs.fetch::<Point>())
|
||||
);
|
||||
let px = idx_to_px(
|
||||
map.xy_idx(tile_x + bounds.x_offset, tile_y + bounds.y_offset),
|
||||
&map
|
||||
);
|
||||
draw.image(atlas.get(id).unwrap()).position(px.0, px.1);
|
||||
}
|
||||
}
|
||||
} else if SHOW_BOUNDARIES {
|
||||
// TODO: Draw boundaries
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw(app: &mut App, gfx: &mut Graphics, gs: &mut State) {
|
||||
let mut draw = gfx.create_draw();
|
||||
draw.clear(Color::BLACK);
|
||||
// Draw map
|
||||
draw_camera(&gs.ecs, &mut draw, &gs.atlas);
|
||||
// Draw player (replace this with draw entities).
|
||||
let map = gs.ecs.fetch::<Map>();
|
||||
for (i, _tile) in map.tiles.iter().enumerate() {
|
||||
let px = idx_to_px(i, &map);
|
||||
draw.image(gs.atlas.get("floor_grass_d").unwrap()).position(px.0, px.1);
|
||||
}
|
||||
let ppos = gs.ecs.fetch::<Point>();
|
||||
let px = idx_to_px(map.xy_idx(ppos.x, ppos.y), &map);
|
||||
let offsets = crate::camera::get_offset();
|
||||
let px = idx_to_px(map.xy_idx(ppos.x + offsets.0, ppos.y + offsets.1), &map);
|
||||
draw.image(gs.atlas.get("ui_heart_full").unwrap()).position(px.0, px.1);
|
||||
// Render batch
|
||||
gfx.render(&draw);
|
||||
|
|
|
|||
|
|
@ -5,21 +5,21 @@ 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<Point>) -> (usize, RGBA) {
|
||||
pub fn get_sprite_for_id(idx: usize, map: &Map, other_pos: Option<Point>) -> (&str, RGBA) {
|
||||
let x = (idx as i32) % map.width;
|
||||
let y = (idx as i32) / map.width;
|
||||
let tile = map.tiles[idx];
|
||||
let base = match tile {
|
||||
let sprite = map.tiles[idx].sprite();
|
||||
/*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 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);
|
||||
return (sprite, 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(
|
||||
|
|
|
|||
|
|
@ -30,27 +30,27 @@ pub enum TileType {
|
|||
}
|
||||
|
||||
impl TileType {
|
||||
pub fn sprite(&self) -> usize {
|
||||
pub fn sprite(&self) -> &str {
|
||||
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,
|
||||
TileType::ImpassableMountain => "statue_warrior",
|
||||
TileType::Wall => "wall_cave_h_a",
|
||||
TileType::DeepWater => "water",
|
||||
TileType::Fence => "wall_cave_h_a",
|
||||
TileType::Bars => "wall_cave_h_a",
|
||||
TileType::Floor => "floor_cobble_a",
|
||||
TileType::WoodFloor => "floor_wood_a",
|
||||
TileType::Gravel => "floor_cobble_b",
|
||||
TileType::Road => "floor_cobble_c",
|
||||
TileType::Grass => "floor_grass_a",
|
||||
TileType::Foliage => "floor_grass_b",
|
||||
TileType::HeavyFoliage => "floor_grass_c",
|
||||
TileType::Sand => "floor_cobble_c",
|
||||
TileType::ShallowWater => "water",
|
||||
TileType::Bridge => "floor_cobble_a",
|
||||
TileType::DownStair => "wall_cave_stair_down",
|
||||
TileType::UpStair => "wall_cave_stair_up",
|
||||
TileType::ToLocal(_) => "wall_crypt_stair_down",
|
||||
TileType::ToOvermap(_) => "wall_crypt_stair_up",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
226
src/player.rs
226
src/player.rs
|
|
@ -40,6 +40,8 @@ use std::cmp::{ max, min };
|
|||
use crate::data::events::*;
|
||||
use crate::data::ids::*;
|
||||
use crate::gui::with_article;
|
||||
use notan::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn try_door(i: i32, j: i32, ecs: &mut World) -> RunState {
|
||||
let mut positions = ecs.write_storage::<Position>();
|
||||
|
|
@ -645,196 +647,118 @@ fn get_item(ecs: &mut World) -> RunState {
|
|||
}
|
||||
}
|
||||
|
||||
use notan::prelude::*;
|
||||
fn try_descend(ecs: &mut World) -> RunState {
|
||||
let dest = try_change_level(ecs, false);
|
||||
let curr_map_id = ecs.fetch::<Map>().id;
|
||||
return match dest {
|
||||
Destination::None => RunState::AwaitingInput,
|
||||
Destination::NextLevel => RunState::GoToLevel(curr_map_id + 1, TileType::UpStair),
|
||||
Destination::PreviousLevel => RunState::GoToLevel(curr_map_id - 1, TileType::DownStair),
|
||||
Destination::ToLocal(id) => RunState::GoToLevel(ID_OVERMAP, TileType::ToLocal(id)),
|
||||
Destination::ToOvermap(id) => RunState::GoToLevel(id, TileType::ToOvermap(id)),
|
||||
};
|
||||
}
|
||||
fn try_ascend(ecs: &mut World) -> RunState {
|
||||
let dest = try_change_level(ecs, true);
|
||||
let curr_map_id = ecs.fetch::<Map>().id;
|
||||
return match dest {
|
||||
Destination::None => RunState::AwaitingInput,
|
||||
Destination::NextLevel => RunState::GoToLevel(curr_map_id + 1, TileType::UpStair),
|
||||
Destination::PreviousLevel => RunState::GoToLevel(curr_map_id - 1, TileType::DownStair),
|
||||
Destination::ToLocal(id) => RunState::GoToLevel(ID_OVERMAP, TileType::ToLocal(id)),
|
||||
Destination::ToOvermap(id) => RunState::GoToLevel(id, TileType::ToOvermap(id)),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn player_input(gs: &mut State, ctx: &mut App, on_overmap: bool) -> RunState {
|
||||
let key = &ctx.keyboard;
|
||||
if key.was_pressed(KeyCode::Numpad4) {
|
||||
return try_move_player(-1, 0, &mut gs.ecs);
|
||||
} else if key.was_pressed(KeyCode::Numpad6) {
|
||||
return try_move_player(1, 0, &mut gs.ecs);
|
||||
} else if key.was_pressed(KeyCode::Numpad8) {
|
||||
return try_move_player(0, -1, &mut gs.ecs);
|
||||
} else if key.was_pressed(KeyCode::Numpad2) {
|
||||
return try_move_player(0, 1, &mut gs.ecs);
|
||||
} else if key.was_pressed(KeyCode::Numpad9) {
|
||||
return try_move_player(1, -1, &mut gs.ecs);
|
||||
} else if key.was_pressed(KeyCode::Numpad7) {
|
||||
return try_move_player(-1, -1, &mut gs.ecs);
|
||||
} else if key.was_pressed(KeyCode::Numpad3) {
|
||||
return try_move_player(1, 1, &mut gs.ecs);
|
||||
} else if key.was_pressed(KeyCode::Numpad1) {
|
||||
return try_move_player(-1, 1, &mut gs.ecs);
|
||||
} else if key.was_pressed(KeyCode::Period) {
|
||||
if key.shift() {
|
||||
let dest = try_change_level(&mut gs.ecs, false);
|
||||
let curr_map_id = gs.ecs.fetch::<Map>().id;
|
||||
return match dest {
|
||||
// If we have no destination, do nothing.
|
||||
Destination::None => RunState::AwaitingInput,
|
||||
// If we want to go to the next level, go to the up-stair tile of id + 1.
|
||||
Destination::NextLevel => RunState::GoToLevel(curr_map_id + 1, TileType::UpStair),
|
||||
// If we want to go to the previous level, go to the down-stair tile of id - 1.
|
||||
Destination::PreviousLevel =>
|
||||
RunState::GoToLevel(curr_map_id - 1, TileType::DownStair),
|
||||
Destination::ToLocal(id) => RunState::GoToLevel(ID_OVERMAP, TileType::ToLocal(id)),
|
||||
Destination::ToOvermap(id) => RunState::GoToLevel(id, TileType::ToOvermap(id)),
|
||||
};
|
||||
} else {
|
||||
return skip_turn(&mut gs.ecs); // (Wait a turn)
|
||||
}
|
||||
} else if key.was_pressed(KeyCode::Comma) {
|
||||
if key.shift() {
|
||||
let dest = try_change_level(&mut gs.ecs, false);
|
||||
let curr_map_id = gs.ecs.fetch::<Map>().id;
|
||||
return match dest {
|
||||
// If we have no destination, do nothing.
|
||||
Destination::None => RunState::AwaitingInput,
|
||||
// If we want to go to the next level, go to the up-stair tile of id + 1.
|
||||
Destination::NextLevel => RunState::GoToLevel(curr_map_id + 1, TileType::UpStair),
|
||||
// If we want to go to the previous level, go to the down-stair tile of id - 1.
|
||||
Destination::PreviousLevel =>
|
||||
RunState::GoToLevel(curr_map_id - 1, TileType::DownStair),
|
||||
Destination::ToLocal(id) => RunState::GoToLevel(ID_OVERMAP, TileType::ToLocal(id)),
|
||||
Destination::ToOvermap(id) => RunState::GoToLevel(id, TileType::ToOvermap(id)),
|
||||
};
|
||||
} else {
|
||||
return skip_turn(&mut gs.ecs); // (Wait a turn)
|
||||
}
|
||||
}
|
||||
return RunState::AwaitingInput;
|
||||
|
||||
/*match ctx.key {
|
||||
None => {
|
||||
return RunState::AwaitingInput;
|
||||
}
|
||||
Some(key) =>
|
||||
match key {
|
||||
// Cardinals
|
||||
VirtualKeyCode::Left | VirtualKeyCode::Numpad4 | VirtualKeyCode::H => {
|
||||
return try_move_player(-1, 0, &mut gs.ecs);
|
||||
}
|
||||
VirtualKeyCode::Right | VirtualKeyCode::Numpad6 | VirtualKeyCode::L => {
|
||||
return try_move_player(1, 0, &mut gs.ecs);
|
||||
}
|
||||
VirtualKeyCode::Up | VirtualKeyCode::Numpad8 | VirtualKeyCode::K => {
|
||||
return try_move_player(0, -1, &mut gs.ecs);
|
||||
}
|
||||
VirtualKeyCode::Down | VirtualKeyCode::Numpad2 | VirtualKeyCode::J => {
|
||||
return try_move_player(0, 1, &mut gs.ecs);
|
||||
}
|
||||
// Diagonals
|
||||
VirtualKeyCode::Numpad9 | VirtualKeyCode::U => {
|
||||
return try_move_player(1, -1, &mut gs.ecs);
|
||||
}
|
||||
VirtualKeyCode::Numpad7 | VirtualKeyCode::Y => {
|
||||
return try_move_player(-1, -1, &mut gs.ecs);
|
||||
}
|
||||
VirtualKeyCode::Numpad3 | VirtualKeyCode::N => {
|
||||
return try_move_player(1, 1, &mut gs.ecs);
|
||||
}
|
||||
VirtualKeyCode::Numpad1 | VirtualKeyCode::B => {
|
||||
// Movement
|
||||
for keycode in key.pressed.iter() {
|
||||
match *keycode {
|
||||
KeyCode::Numpad1 | KeyCode::B => {
|
||||
return try_move_player(-1, 1, &mut gs.ecs);
|
||||
}
|
||||
// id
|
||||
VirtualKeyCode::Period => {
|
||||
if ctx.shift {
|
||||
let dest = try_change_level(&mut gs.ecs, false);
|
||||
let curr_map_id = gs.ecs.fetch::<Map>().id;
|
||||
return match dest {
|
||||
// If we have no destination, do nothing.
|
||||
Destination::None => RunState::AwaitingInput,
|
||||
// If we want to go to the next level, go to the up-stair tile of id + 1.
|
||||
Destination::NextLevel =>
|
||||
RunState::GoToLevel(curr_map_id + 1, TileType::UpStair),
|
||||
// If we want to go to the previous level, go to the down-stair tile of id - 1.
|
||||
Destination::PreviousLevel =>
|
||||
RunState::GoToLevel(curr_map_id - 1, TileType::DownStair),
|
||||
Destination::ToLocal(id) =>
|
||||
RunState::GoToLevel(ID_OVERMAP, TileType::ToLocal(id)),
|
||||
Destination::ToOvermap(id) =>
|
||||
RunState::GoToLevel(id, TileType::ToOvermap(id)),
|
||||
};
|
||||
} else {
|
||||
return skip_turn(&mut gs.ecs); // (Wait a turn)
|
||||
KeyCode::Numpad2 | KeyCode::Down | KeyCode::J => {
|
||||
return try_move_player(0, 1, &mut gs.ecs);
|
||||
}
|
||||
KeyCode::Numpad3 | KeyCode::N => {
|
||||
return try_move_player(1, 1, &mut gs.ecs);
|
||||
}
|
||||
KeyCode::Numpad4 | KeyCode::Left | KeyCode::H => {
|
||||
return try_move_player(-1, 0, &mut gs.ecs);
|
||||
}
|
||||
KeyCode::Numpad6 | KeyCode::Right | KeyCode::L => {
|
||||
return try_move_player(1, 0, &mut gs.ecs);
|
||||
}
|
||||
KeyCode::Numpad7 | KeyCode::Y => {
|
||||
return try_move_player(-1, -1, &mut gs.ecs);
|
||||
}
|
||||
KeyCode::Numpad8 | KeyCode::Up | KeyCode::K => {
|
||||
return try_move_player(0, -1, &mut gs.ecs);
|
||||
}
|
||||
KeyCode::Numpad9 | KeyCode::U => {
|
||||
return try_move_player(1, -1, &mut gs.ecs);
|
||||
}
|
||||
KeyCode::Period => {
|
||||
if key.shift() {
|
||||
return try_descend(&mut gs.ecs);
|
||||
}
|
||||
return skip_turn(&mut gs.ecs);
|
||||
}
|
||||
KeyCode::Comma => {
|
||||
if key.shift() {
|
||||
return try_ascend(&mut gs.ecs);
|
||||
}
|
||||
}
|
||||
VirtualKeyCode::Comma => {
|
||||
if ctx.shift {
|
||||
let dest = try_change_level(&mut gs.ecs, true);
|
||||
let curr_map_id = gs.ecs.fetch::<Map>().id;
|
||||
return match dest {
|
||||
Destination::None => RunState::AwaitingInput,
|
||||
Destination::NextLevel =>
|
||||
RunState::GoToLevel(curr_map_id + 1, TileType::UpStair),
|
||||
Destination::PreviousLevel =>
|
||||
RunState::GoToLevel(curr_map_id - 1, TileType::DownStair),
|
||||
Destination::ToLocal(id) =>
|
||||
RunState::GoToLevel(ID_OVERMAP, TileType::ToLocal(id)),
|
||||
Destination::ToOvermap(id) =>
|
||||
RunState::GoToLevel(id, TileType::ToOvermap(id)),
|
||||
};
|
||||
}
|
||||
}
|
||||
VirtualKeyCode::Slash => {
|
||||
if ctx.shift {
|
||||
KeyCode::Slash => {
|
||||
if key.shift() {
|
||||
return RunState::HelpScreen;
|
||||
}
|
||||
}
|
||||
VirtualKeyCode::NumpadDecimal => {
|
||||
return skip_turn(&mut gs.ecs);
|
||||
}
|
||||
|
||||
// Items
|
||||
VirtualKeyCode::C => {
|
||||
KeyCode::C => {
|
||||
if !on_overmap {
|
||||
return RunState::ActionWithDirection { function: try_door };
|
||||
}
|
||||
}
|
||||
VirtualKeyCode::O => {
|
||||
KeyCode::O => {
|
||||
if !on_overmap {
|
||||
return RunState::ActionWithDirection { function: open };
|
||||
}
|
||||
}
|
||||
VirtualKeyCode::F => {
|
||||
KeyCode::F => {
|
||||
if !on_overmap {
|
||||
return RunState::ActionWithDirection { function: kick };
|
||||
}
|
||||
}
|
||||
VirtualKeyCode::G => {
|
||||
KeyCode::G => {
|
||||
return get_item(&mut gs.ecs);
|
||||
}
|
||||
VirtualKeyCode::I => {
|
||||
KeyCode::I => {
|
||||
return RunState::ShowInventory;
|
||||
}
|
||||
VirtualKeyCode::D => {
|
||||
KeyCode::D => {
|
||||
return RunState::ShowDropItem;
|
||||
}
|
||||
VirtualKeyCode::R => {
|
||||
KeyCode::R => {
|
||||
return RunState::ShowRemoveItem;
|
||||
}
|
||||
// Other
|
||||
VirtualKeyCode::Minus => {
|
||||
KeyCode::Minus => {
|
||||
return RunState::ShowCheatMenu;
|
||||
}
|
||||
VirtualKeyCode::Escape => {
|
||||
KeyCode::Escape => {
|
||||
return RunState::SaveGame;
|
||||
}
|
||||
VirtualKeyCode::X => {
|
||||
let (min_x, _max_x, min_y, _max_y, x_offset, y_offset) = get_screen_bounds(
|
||||
&gs.ecs,
|
||||
ctx
|
||||
);
|
||||
KeyCode::X => {
|
||||
let (min_x, _max_x, min_y, _max_y, x_offset, y_offset) = get_screen_bounds(&gs.ecs);
|
||||
let ppos = gs.ecs.fetch::<Point>();
|
||||
let (x, y) = (ppos.x + x_offset - min_x, ppos.y + y_offset - min_y);
|
||||
return RunState::Farlook { x, y };
|
||||
}
|
||||
_ => {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
return RunState::AwaitingInput;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RunState::AwaitingInput;*/
|
||||
}
|
||||
|
||||
fn try_change_level(ecs: &mut World, backtracking: bool) -> Destination {
|
||||
let player_pos = ecs.fetch::<Point>();
|
||||
|
|
|
|||
|
|
@ -296,6 +296,8 @@ impl State {
|
|||
}
|
||||
damage_system::delete_the_dead(&mut self.ecs);
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
fn tick(&mut self, ctx: &mut BTerm) {
|
||||
let mut new_runstate;
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue