aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/src/world/mod.rs36
-rw-r--r--renderer/src/main.rs25
-rw-r--r--renderer/src/map.rs62
-rw-r--r--renderer/src/tee.rs46
4 files changed, 129 insertions, 40 deletions
diff --git a/client/src/world/mod.rs b/client/src/world/mod.rs
index ae985a6..bbc505c 100644
--- a/client/src/world/mod.rs
+++ b/client/src/world/mod.rs
@@ -1,10 +1,9 @@
+use self::map::Map;
+use crate::client::{helper::get_map_path, ClientMesgOut};
use gamenet::{
enums::{Emote, Team, Weapon},
SnapObj,
};
-
-use self::map::Map;
-use crate::client::{helper::get_map_path, ClientMesgOut};
use std::{collections::BTreeMap, fs::File};
pub mod map;
@@ -13,6 +12,10 @@ pub use gamenet::enums;
#[derive(Debug)]
pub struct Tee {
+ pub name: String,
+ pub skin: String,
+ pub clan: String,
+
pub local: bool,
pub latency: i32,
pub score: i32,
@@ -62,6 +65,9 @@ impl Default for Tee {
hook_dy: Default::default(),
hook_player: Default::default(),
hook_state: Default::default(),
+ name: Default::default(),
+ skin: Default::default(),
+ clan: Default::default(),
}
}
}
@@ -88,19 +94,20 @@ impl World {
ClientMesgOut::Snaps(s) => {
self.tees.clear();
for (id, o) in s {
+ let e = self.tees.entry(*id).or_default();
match o {
- SnapObj::ClientInfo(_o) => {
- // TODO
+ SnapObj::ClientInfo(o) => {
+ e.name = i32_to_string(o.name);
+ e.skin = i32_to_string(o.skin);
+ e.clan = i32_to_string(o.clan);
}
SnapObj::PlayerInfo(o) => {
- let e = self.tees.entry(*id).or_default();
e.local = o.local == 1;
e.team = o.team;
e.latency = o.latency;
e.score = o.score;
}
SnapObj::Character(c) => {
- let e = self.tees.entry(*id).or_default();
e.ammo = c.ammo_count;
e.weapon = c.weapon;
e.emote = c.emote;
@@ -130,3 +137,18 @@ impl World {
self.tees.values().find(|e| e.local)
}
}
+
+fn i32_to_string<const S: usize>(k: [i32; S]) -> String {
+ let mut bytes = vec![];
+ for i in 0..S {
+ bytes.push(((((k[i]) >> 24) & 0xff) - 128) as u8);
+ bytes.push(((((k[i]) >> 16) & 0xff) - 128) as u8);
+ bytes.push(((((k[i]) >> 8) & 0xff) - 128) as u8);
+ bytes.push((((k[i]) & 0xff) - 128) as u8);
+ }
+ let len = bytes.iter().position(|e| *e == 0).unwrap_or(S);
+ while bytes.len() > len {
+ bytes.pop();
+ }
+ String::from_utf8(bytes).unwrap()
+}
diff --git a/renderer/src/main.rs b/renderer/src/main.rs
index d4ee57d..63396cc 100644
--- a/renderer/src/main.rs
+++ b/renderer/src/main.rs
@@ -1,4 +1,5 @@
pub mod map;
+pub mod tee;
use glutin::{
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
@@ -20,6 +21,7 @@ use std::{
collections::HashSet, convert::TryInto, net::IpAddr, process::exit, str::FromStr,
sync::atomic::Ordering, thread, time::Duration,
};
+use tee::TeeRenderer;
use twclient::{
client::{Client, ClientConfig, ClientInterface, ClientMesgIn, PlayerInput},
world::World,
@@ -111,6 +113,7 @@ fn main() {
let mut renderer = Renderer {
client_interface,
+ tee_renderer: TeeRenderer::new(),
map_renderer: MapRenderer::new(),
world: World::new(),
input: PlayerInput::default(),
@@ -206,6 +209,7 @@ fn main() {
pub struct Renderer {
client_interface: ClientInterface,
map_renderer: MapRenderer,
+ tee_renderer: TeeRenderer,
world: World,
input: PlayerInput,
}
@@ -231,26 +235,7 @@ impl Renderer {
canvas.translate((-center.0 as f32, -center.1 as f32));
self.map_renderer.draw(&self.world, canvas);
-
- let tee_paint = Paint::new(
- Color4f {
- a: 1.0,
- r: 0.2,
- g: 0.0,
- b: 0.2,
- },
- &ColorSpace::new_srgb(),
- );
- for t in self.world.tees.values() {
- canvas.draw_circle(
- Point {
- x: t.x as f32,
- y: t.y as f32,
- },
- 16.0,
- &tee_paint,
- );
- }
+ self.tee_renderer.draw(&self.world, canvas);
canvas.restore();
}
diff --git a/renderer/src/map.rs b/renderer/src/map.rs
index 8ce932f..f7672c1 100644
--- a/renderer/src/map.rs
+++ b/renderer/src/map.rs
@@ -2,7 +2,8 @@ use std::collections::HashMap;
use log::{info, warn};
use skia_safe::{
- canvas::SrcRectConstraint, BlendMode, Canvas, Color4f, ColorSpace, ISize, Image, Paint, Rect,
+ canvas::SrcRectConstraint, BlendMode, Canvas, Color4f, ColorSpace, ISize, Image, Matrix, Paint,
+ Rect,
};
use twclient::world::{
map::{format, TILE_NUM},
@@ -51,6 +52,7 @@ impl MapRenderer {
}
pub fn draw(&mut self, world: &World, canvas: &mut Canvas) {
+ let rot90 = Matrix::rotate_deg(90.0);
let mut grid_paint = Paint::new(
Color4f {
a: 1.0,
@@ -89,22 +91,14 @@ impl MapRenderer {
let layer_x = layer_x.try_into().unwrap_or(0);
let layer_y = layer_y.try_into().unwrap_or(0);
- let tile_rect = Rect {
- top: layer_y as f32 * TILE_SIZE,
- left: layer_x as f32 * TILE_SIZE,
- bottom: layer_y as f32 * TILE_SIZE + TILE_SIZE,
- right: layer_x as f32 * TILE_SIZE + TILE_SIZE,
- };
- // canvas.draw_rect(tile_rect, &grid_paint);
-
let tile = match l.tiles.get((layer_y, layer_x)) {
Some(t) => t,
None => continue,
};
- let _rotate = tile.flags & format::TILEFLAG_ROTATE != 0;
- let _vflip = tile.flags & format::TILEFLAG_VFLIP != 0;
- let _hflip = tile.flags & format::TILEFLAG_HFLIP != 0;
+ let rotate = tile.flags & format::TILEFLAG_ROTATE != 0;
+ let vflip = tile.flags & format::TILEFLAG_VFLIP != 0;
+ let hflip = tile.flags & format::TILEFLAG_HFLIP != 0;
let tile_x = tile.index as u32 % TILE_NUM;
let tile_y = tile.index as u32 / TILE_NUM;
@@ -112,6 +106,21 @@ impl MapRenderer {
continue;
}
+ canvas.save();
+ canvas.translate((
+ (layer_x as f32 + 0.5) * TILE_SIZE,
+ (layer_y as f32 + 0.5) * TILE_SIZE,
+ ));
+ if rotate {
+ canvas.concat(&rot90);
+ }
+ if vflip {
+ canvas.scale((-1.0, 1.0));
+ }
+ if hflip {
+ canvas.scale((1.0, -1.0));
+ }
+
const TL: u32 = 64;
canvas.draw_image_rect(
tileset,
@@ -124,9 +133,36 @@ impl MapRenderer {
},
SrcRectConstraint::Strict,
)),
- tile_rect,
+ Rect {
+ top: -TILE_SIZE / 2.0,
+ bottom: TILE_SIZE / 2.0,
+ left: -TILE_SIZE / 2.0,
+ right: TILE_SIZE / 2.0,
+ },
&layer_tint,
);
+
+ // if hflip {
+ // canvas.draw_rect(
+ // Rect {
+ // top: -TILE_SIZE / 2.0,
+ // bottom: TILE_SIZE / 2.0,
+ // left: -TILE_SIZE / 2.0,
+ // right: TILE_SIZE / 2.0,
+ // },
+ // &Paint::new(
+ // Color4f {
+ // a: 0.5,
+ // b: 1.0,
+ // g: 0.0,
+ // r: 1.0,
+ // },
+ // &ColorSpace::new_srgb(),
+ // ),
+ // );
+ // }
+
+ canvas.restore();
}
}
}
diff --git a/renderer/src/tee.rs b/renderer/src/tee.rs
new file mode 100644
index 0000000..98ac218
--- /dev/null
+++ b/renderer/src/tee.rs
@@ -0,0 +1,46 @@
+use skia_safe::{Canvas, Color4f, ColorSpace, Font, Paint, Point};
+use twclient::world::World;
+
+const TEE_RADIUS: f32 = 16.0;
+
+pub struct TeeRenderer {}
+
+impl TeeRenderer {
+ pub fn new() -> Self {
+ Self {}
+ }
+
+ pub fn draw(&mut self, world: &World, canvas: &mut Canvas) {
+ let tee_paint = Paint::new(
+ Color4f {
+ a: 1.0,
+ r: 0.2,
+ g: 0.0,
+ b: 0.2,
+ },
+ &ColorSpace::new_srgb(),
+ );
+ let name_paint = Paint::new(
+ Color4f {
+ a: 1.0,
+ r: 1.0,
+ g: 1.0,
+ b: 0.0,
+ },
+ &ColorSpace::new_srgb(),
+ );
+ for t in world.tees.values() {
+ let origin = Point {
+ x: t.x as f32,
+ y: t.y as f32,
+ };
+ canvas.draw_circle(origin, TEE_RADIUS, &tee_paint);
+ canvas.draw_str(
+ t.name.as_str(),
+ (origin.x, origin.y - 20.0),
+ &Font::default(),
+ &name_paint,
+ );
+ }
+ }
+}