Reformat using rustfmt
This commit is contained in:
parent
ffc9ac0e47
commit
3704b9eeb8
|
@ -42,8 +42,12 @@ impl Var for CVar<String> {
|
|||
Box::new((&input[1..input.len() - 1]).to_owned())
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str { self.description }
|
||||
fn can_serialize(&self) -> bool { self.serializable }
|
||||
fn description(&self) -> &'static str {
|
||||
self.description
|
||||
}
|
||||
fn can_serialize(&self) -> bool {
|
||||
self.serializable
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Var {
|
||||
|
@ -67,26 +71,22 @@ pub struct Console {
|
|||
|
||||
impl Console {
|
||||
pub fn new() -> Console {
|
||||
let mut con = Console {
|
||||
Console {
|
||||
names: HashMap::new(),
|
||||
vars: HashMap::new(),
|
||||
var_values: HashMap::new(),
|
||||
|
||||
history: Vec::with_capacity(200),
|
||||
history: vec![Component::Text(TextComponent::new("")); 200],
|
||||
|
||||
collection: ui::Collection::new(),
|
||||
active: false,
|
||||
position: -220.0,
|
||||
};
|
||||
for _ in 0 .. 200 {
|
||||
con.history.push(Component::Text(
|
||||
TextComponent::new("")
|
||||
));
|
||||
}
|
||||
con
|
||||
}
|
||||
|
||||
pub fn register<T: Sized + Any>(&mut self, var: CVar<T>) where CVar<T> : Var {
|
||||
pub fn register<T: Sized + Any>(&mut self, var: CVar<T>)
|
||||
where CVar<T>: Var
|
||||
{
|
||||
if self.vars.contains_key(var.name) {
|
||||
panic!("Key registered twice {}", var.name);
|
||||
}
|
||||
|
@ -95,12 +95,16 @@ impl Console {
|
|||
self.vars.insert(var.name, Box::new(var));
|
||||
}
|
||||
|
||||
pub fn get<T: Sized + Any>(&self, var: CVar<T>) -> &T where CVar<T> : Var {
|
||||
pub fn get<T: Sized + Any>(&self, var: CVar<T>) -> &T
|
||||
where CVar<T>: Var
|
||||
{
|
||||
// Should never fail
|
||||
self.var_values.get(var.name).unwrap().downcast_ref::<T>().unwrap()
|
||||
}
|
||||
|
||||
pub fn set<T: Sized + Any>(&mut self, var: CVar<T>, val: T) where CVar<T> : Var {
|
||||
pub fn set<T: Sized + Any>(&mut self, var: CVar<T>, val: T)
|
||||
where CVar<T>: Var
|
||||
{
|
||||
self.var_values.insert(var.name, Box::new(val));
|
||||
self.save_config();
|
||||
}
|
||||
|
@ -113,7 +117,11 @@ impl Console {
|
|||
self.active = !self.active;
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, ui_container: &mut ui::Container, renderer: &mut render::Renderer, delta: f64, width: f64) {
|
||||
pub fn tick(&mut self,
|
||||
ui_container: &mut ui::Container,
|
||||
renderer: &mut render::Renderer,
|
||||
delta: f64,
|
||||
width: f64) {
|
||||
// To make sure the console is always on top it constant removes and readds itself.
|
||||
// Its hacky but the console should never appear for normal users so its not really
|
||||
// a major issue.
|
||||
|
@ -139,12 +147,20 @@ impl Console {
|
|||
ui::Mode::Unscaled(scale) => 854.0 / scale,
|
||||
};
|
||||
|
||||
let mut background = ui::Image::new(
|
||||
render::Renderer::get_texture(renderer.get_textures_ref(), "steven:solid"),
|
||||
0.0, self.position, w, 220.0,
|
||||
0.0, 0.0, 1.0, 1.0,
|
||||
0, 0, 0
|
||||
);
|
||||
let mut background =
|
||||
ui::Image::new(render::Renderer::get_texture(renderer.get_textures_ref(),
|
||||
"steven:solid"),
|
||||
0.0,
|
||||
self.position,
|
||||
w,
|
||||
220.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
background.set_a(180);
|
||||
let background = self.collection.add(ui_container.add(background));
|
||||
|
||||
|
@ -154,7 +170,11 @@ impl Console {
|
|||
if offset >= 210.0 {
|
||||
break;
|
||||
}
|
||||
let mut fmt = ui::Formatted::with_width_limit(renderer, line.clone(), 5.0, 5.0 + offset, w - 1.0);
|
||||
let mut fmt = ui::Formatted::with_width_limit(renderer,
|
||||
line.clone(),
|
||||
5.0,
|
||||
5.0 + offset,
|
||||
w - 1.0);
|
||||
fmt.set_parent(&background);
|
||||
fmt.set_v_attach(ui::VAttach::Bottom);
|
||||
offset += fmt.get_height();
|
||||
|
@ -197,7 +217,11 @@ impl Console {
|
|||
for line in var.description().lines() {
|
||||
write!(file, "# {}\n", line).unwrap();
|
||||
}
|
||||
write!(file, "{} {}\n\n", name, var.serialize(self.var_values.get(name).unwrap())).unwrap();
|
||||
write!(file,
|
||||
"{} {}\n\n",
|
||||
name,
|
||||
var.serialize(self.var_values.get(name).unwrap()))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,7 +230,11 @@ impl Console {
|
|||
if let Some(pos) = file.rfind("src/") {
|
||||
file = &file[pos + 4..];
|
||||
}
|
||||
println!("[{}:{}][{}] {}", file, record.location().line(), record.level(), record.args());
|
||||
println!("[{}:{}][{}] {}",
|
||||
file,
|
||||
record.location().line(),
|
||||
record.level(),
|
||||
record.args());
|
||||
self.history.remove(0);
|
||||
let mut msg = TextComponent::new("");
|
||||
msg.modifier.extra = Some(vec![
|
||||
|
@ -238,9 +266,7 @@ impl Console {
|
|||
Component::Text(TextComponent::new("] ")),
|
||||
Component::Text(TextComponent::new(&format!("{}", record.args())))
|
||||
]);
|
||||
self.history.push(Component::Text(
|
||||
msg
|
||||
));
|
||||
self.history.push(Component::Text(msg));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,9 +276,7 @@ pub struct ConsoleProxy {
|
|||
|
||||
impl ConsoleProxy {
|
||||
pub fn new(con: Arc<Mutex<Console>>) -> ConsoleProxy {
|
||||
ConsoleProxy {
|
||||
console: con,
|
||||
}
|
||||
ConsoleProxy { console: con }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,19 +18,25 @@ use std::mem;
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Component {
|
||||
Text(TextComponent)
|
||||
Text(TextComponent),
|
||||
}
|
||||
|
||||
impl Component {
|
||||
pub fn from_value(v: &serde_json::Value) -> Self {
|
||||
let mut modifier = Modifier::from_value(v);
|
||||
if let Some(val) = v.as_string() {
|
||||
Component::Text(TextComponent{text: val.to_owned(), modifier: modifier})
|
||||
Component::Text(TextComponent {
|
||||
text: val.to_owned(),
|
||||
modifier: modifier,
|
||||
})
|
||||
} else if v.find("text").is_some() {
|
||||
Component::Text(TextComponent::from_value(v, modifier))
|
||||
} else {
|
||||
modifier.color = Some(Color::RGB(255, 0, 0));
|
||||
Component::Text(TextComponent{text: "UNHANDLED".to_owned(), modifier: modifier})
|
||||
Component::Text(TextComponent {
|
||||
text: "UNHANDLED".to_owned(),
|
||||
modifier: modifier,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,7 +55,10 @@ impl fmt::Display for Component {
|
|||
|
||||
impl Default for Component {
|
||||
fn default() -> Self {
|
||||
Component::Text(TextComponent{text: "".to_owned(), modifier: Default::default()})
|
||||
Component::Text(TextComponent {
|
||||
text: "".to_owned(),
|
||||
modifier: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,12 +71,10 @@ pub struct Modifier {
|
|||
pub strikethrough: Option<bool>,
|
||||
pub obfuscated: Option<bool>,
|
||||
pub color: Option<Color>,
|
||||
|
||||
// click_event
|
||||
// hover_event
|
||||
// insertion
|
||||
}
|
||||
|
||||
// TODO: Missing events click/hover/insert
|
||||
|
||||
impl Modifier {
|
||||
pub fn from_value(v: &serde_json::Value) -> Self {
|
||||
let mut m = Modifier {
|
||||
|
@ -76,7 +83,9 @@ impl Modifier {
|
|||
underlined: v.find("underlined").map_or(Option::None, |v| v.as_boolean()),
|
||||
strikethrough: v.find("strikethrough").map_or(Option::None, |v| v.as_boolean()),
|
||||
obfuscated: v.find("obfuscated").map_or(Option::None, |v| v.as_boolean()),
|
||||
color: v.find("color").map_or(Option::None, |v| v.as_string()).map(|v| Color::from_string(&v.to_owned())),
|
||||
color: v.find("color")
|
||||
.map_or(Option::None, |v| v.as_string())
|
||||
.map(|v| Color::from_string(&v.to_owned())),
|
||||
extra: Option::None,
|
||||
};
|
||||
if let Some(extra) = v.find("extra") {
|
||||
|
@ -106,9 +115,7 @@ impl TextComponent {
|
|||
pub fn new(val: &str) -> TextComponent {
|
||||
TextComponent {
|
||||
text: val.to_owned(),
|
||||
modifier: Modifier {
|
||||
.. Default::default()
|
||||
}
|
||||
modifier: Modifier { ..Default::default() },
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +161,7 @@ pub enum Color {
|
|||
LightPurple,
|
||||
Yellow,
|
||||
White,
|
||||
RGB(u8, u8, u8)
|
||||
RGB(u8, u8, u8),
|
||||
}
|
||||
|
||||
impl fmt::Display for Color {
|
||||
|
@ -195,11 +202,7 @@ impl Color {
|
|||
Ok(b) => b,
|
||||
Err(_) => return Color::White,
|
||||
};
|
||||
Color::RGB(
|
||||
r,
|
||||
g,
|
||||
b
|
||||
)
|
||||
Color::RGB(r, g, b)
|
||||
}
|
||||
_ => Color::White,
|
||||
}
|
||||
|
@ -264,12 +267,12 @@ fn test_color_from() {
|
|||
}
|
||||
let test = Color::from_string(&"red".to_owned());
|
||||
match test {
|
||||
Color::Red => {},
|
||||
Color::Red => {}
|
||||
_ => panic!("Wrong type"),
|
||||
}
|
||||
let test = Color::from_string(&"dark_blue".to_owned());
|
||||
match test {
|
||||
Color::DarkBlue => {},
|
||||
Color::DarkBlue => {}
|
||||
_ => panic!("Wrong type"),
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +303,8 @@ pub fn convert_legacy(c: &mut Component) {
|
|||
current.text = txt.text[last..i].to_owned();
|
||||
last = next.0 + 1;
|
||||
|
||||
let mut modifier = if (color_char >= 'a' && color_char <= 'f') || (color_char >= '0' && color_char <= '9') {
|
||||
let mut modifier = if (color_char >= 'a' && color_char <= 'f') ||
|
||||
(color_char >= '0' && color_char <= '9') {
|
||||
Default::default()
|
||||
} else {
|
||||
current.modifier.clone()
|
||||
|
@ -331,7 +335,7 @@ pub fn convert_legacy(c: &mut Component) {
|
|||
'm' => modifier.strikethrough = Some(true),
|
||||
'n' => modifier.underlined = Some(true),
|
||||
'o' => modifier.italic = Some(true),
|
||||
'r' => {},
|
||||
'r' => {}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
|
||||
|
@ -352,6 +356,6 @@ pub fn convert_legacy(c: &mut Component) {
|
|||
}
|
||||
txt.text = "".to_owned();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
176
src/gl/mod.rs
176
src/gl/mod.rs
|
@ -48,13 +48,17 @@ pub fn draw_elements(ty: DrawType, count: usize, dty: Type, offset: usize) {
|
|||
|
||||
/// Sets the size of the viewport of this context.
|
||||
pub fn viewport(x: i32, y: i32, w: i32, h: i32) {
|
||||
unsafe { gl::Viewport(x, y, w, h); }
|
||||
unsafe {
|
||||
gl::Viewport(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the color the color buffer should be cleared to
|
||||
/// when Clear is called with the color flag.
|
||||
pub fn clear_color(r: f32, g: f32, b: f32, a: f32) {
|
||||
unsafe { gl::ClearColor(r, g, b, a); }
|
||||
unsafe {
|
||||
gl::ClearColor(r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
/// ClearFlags is a set of flags to mark what should be cleared during
|
||||
|
@ -64,7 +68,7 @@ pub enum ClearFlags {
|
|||
Color,
|
||||
/// Marks the depth buffer to be cleared
|
||||
Depth,
|
||||
Internal(u32)
|
||||
Internal(u32),
|
||||
}
|
||||
|
||||
impl ClearFlags {
|
||||
|
@ -72,7 +76,7 @@ impl ClearFlags {
|
|||
match self {
|
||||
ClearFlags::Color => gl::COLOR_BUFFER_BIT,
|
||||
ClearFlags::Depth => gl::DEPTH_BUFFER_BIT,
|
||||
ClearFlags::Internal(val) => val
|
||||
ClearFlags::Internal(val) => val,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +105,9 @@ pub const ALWAYS: Func = gl::ALWAYS;
|
|||
pub const EQUAL: Func = gl::EQUAL;
|
||||
|
||||
pub fn depth_func(f: Func) {
|
||||
unsafe { gl::DepthFunc(f); }
|
||||
unsafe {
|
||||
gl::DepthFunc(f);
|
||||
}
|
||||
}
|
||||
|
||||
/// Flag is a setting that can be enabled or disabled on the context.
|
||||
|
@ -115,18 +121,24 @@ pub const MULTISAMPLE: Flag = gl::MULTISAMPLE;
|
|||
|
||||
/// Enables the passed flag.
|
||||
pub fn enable(f: Flag) {
|
||||
unsafe { gl::Enable(f); }
|
||||
unsafe {
|
||||
gl::Enable(f);
|
||||
}
|
||||
}
|
||||
|
||||
/// Disables the passed flag.
|
||||
pub fn disable(f: Flag) {
|
||||
unsafe { gl::Disable(f); }
|
||||
unsafe {
|
||||
gl::Disable(f);
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the texture slot with the passed id as the
|
||||
/// currently active one.
|
||||
pub fn active_texture(id: u32) {
|
||||
unsafe { gl::ActiveTexture(gl::TEXTURE0 + id); }
|
||||
unsafe {
|
||||
gl::ActiveTexture(gl::TEXTURE0 + id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Factor is used in blending
|
||||
|
@ -138,7 +150,9 @@ pub const ZERO_FACTOR: Factor = gl::ZERO;
|
|||
|
||||
/// Sets the factors to be used when blending.
|
||||
pub fn blend_func(s_factor: Factor, d_factor: Factor) {
|
||||
unsafe { gl::BlendFunc(s_factor, d_factor); }
|
||||
unsafe {
|
||||
gl::BlendFunc(s_factor, d_factor);
|
||||
}
|
||||
}
|
||||
|
||||
// Face specifies a face to act on.
|
||||
|
@ -148,7 +162,9 @@ pub const FRONT: Face = gl::FRONT;
|
|||
|
||||
/// Sets the face to be culled by the gpu.
|
||||
pub fn cull_face(face: Face) {
|
||||
unsafe { gl::CullFace(face); }
|
||||
unsafe {
|
||||
gl::CullFace(face);
|
||||
}
|
||||
}
|
||||
|
||||
// FaceDirection is used to specify an order of vertices, normally
|
||||
|
@ -219,7 +235,9 @@ impl Texture {
|
|||
// Allocates a new texture.
|
||||
pub fn new() -> Texture {
|
||||
let mut t = Texture(0);
|
||||
unsafe { gl::GenTextures(1, &mut t.0); }
|
||||
unsafe {
|
||||
gl::GenTextures(1, &mut t.0);
|
||||
}
|
||||
t
|
||||
}
|
||||
|
||||
|
@ -230,25 +248,75 @@ impl Texture {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_pixels(&self, target: TextureTarget, level: i32, format: TextureFormat, ty: Type, pixels: &mut [u8]) {
|
||||
pub fn get_pixels(&self,
|
||||
target: TextureTarget,
|
||||
level: i32,
|
||||
format: TextureFormat,
|
||||
ty: Type,
|
||||
pixels: &mut [u8]) {
|
||||
unsafe {
|
||||
gl::GetTexImage(target, level, format, ty, pixels.as_mut_ptr() as *mut gl::types::GLvoid);
|
||||
gl::GetTexImage(target,
|
||||
level,
|
||||
format,
|
||||
ty,
|
||||
pixels.as_mut_ptr() as *mut gl::types::GLvoid);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn image_3d(&self, target: TextureTarget, level: i32, width: u32, height: u32, depth: u32, format: TextureFormat, ty: Type, pix: &[u8]) {
|
||||
pub fn image_3d(&self,
|
||||
target: TextureTarget,
|
||||
level: i32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
depth: u32,
|
||||
format: TextureFormat,
|
||||
ty: Type,
|
||||
pix: &[u8]) {
|
||||
unsafe {
|
||||
gl::TexImage3D(target, level, format as i32, width as i32, height as i32, depth as i32, 0, format, ty, pix.as_ptr() as *const gl::types::GLvoid);
|
||||
gl::TexImage3D(target,
|
||||
level,
|
||||
format as i32,
|
||||
width as i32,
|
||||
height as i32,
|
||||
depth as i32,
|
||||
0,
|
||||
format,
|
||||
ty,
|
||||
pix.as_ptr() as *const gl::types::GLvoid);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sub_image_3d(&self, target: TextureTarget, level: i32, x: u32, y: u32, z: u32, width: u32, height: u32, depth: u32, format: TextureFormat, ty: Type, pix: &[u8]) {
|
||||
pub fn sub_image_3d(&self,
|
||||
target: TextureTarget,
|
||||
level: i32,
|
||||
x: u32,
|
||||
y: u32,
|
||||
z: u32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
depth: u32,
|
||||
format: TextureFormat,
|
||||
ty: Type,
|
||||
pix: &[u8]) {
|
||||
unsafe {
|
||||
gl::TexSubImage3D(target, level, x as i32, y as i32, z as i32, width as i32, height as i32, depth as i32, format, ty, pix.as_ptr() as *const gl::types::GLvoid);
|
||||
gl::TexSubImage3D(target,
|
||||
level,
|
||||
x as i32,
|
||||
y as i32,
|
||||
z as i32,
|
||||
width as i32,
|
||||
height as i32,
|
||||
depth as i32,
|
||||
format,
|
||||
ty,
|
||||
pix.as_ptr() as *const gl::types::GLvoid);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_parameter(&self, target: TextureTarget, param: TextureParameter, value: TextureValue) {
|
||||
pub fn set_parameter(&self,
|
||||
target: TextureTarget,
|
||||
param: TextureParameter,
|
||||
value: TextureValue) {
|
||||
unsafe {
|
||||
gl::TexParameteri(target, param, value);
|
||||
}
|
||||
|
@ -257,7 +325,9 @@ impl Texture {
|
|||
|
||||
impl Drop for Texture {
|
||||
fn drop(&mut self) {
|
||||
unsafe { gl::DeleteTextures(1, &self.0); }
|
||||
unsafe {
|
||||
gl::DeleteTextures(1, &self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,17 +368,23 @@ impl Program {
|
|||
}
|
||||
|
||||
pub fn uniform_location(&self, name: &str) -> Uniform {
|
||||
Uniform(unsafe { gl::GetUniformLocation(self.0, ffi::CString::new(name).unwrap().as_ptr()) } )
|
||||
Uniform(unsafe {
|
||||
gl::GetUniformLocation(self.0, ffi::CString::new(name).unwrap().as_ptr())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn attribute_location(&self, name: &str) -> Attribute {
|
||||
Attribute(unsafe { gl::GetAttribLocation(self.0, ffi::CString::new(name).unwrap().as_ptr()) })
|
||||
Attribute(unsafe {
|
||||
gl::GetAttribLocation(self.0, ffi::CString::new(name).unwrap().as_ptr())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Program {
|
||||
fn drop(&mut self) {
|
||||
unsafe { gl::DeleteProgram(self.0); }
|
||||
unsafe {
|
||||
gl::DeleteProgram(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,7 +397,10 @@ impl Shader {
|
|||
|
||||
pub fn set_source(&self, src: &str) {
|
||||
unsafe {
|
||||
gl::ShaderSource(self.0, 1, &ffi::CString::new(src).unwrap().as_ptr(), ptr::null());
|
||||
gl::ShaderSource(self.0,
|
||||
1,
|
||||
&ffi::CString::new(src).unwrap().as_ptr(),
|
||||
ptr::null());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,7 +412,9 @@ impl Shader {
|
|||
|
||||
pub fn get_parameter(&self, param: ShaderParameter) -> i32 {
|
||||
let mut ret: i32 = 0;
|
||||
unsafe { gl::GetShaderiv(self.0, param, &mut ret); }
|
||||
unsafe {
|
||||
gl::GetShaderiv(self.0, param, &mut ret);
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
|
@ -406,13 +487,22 @@ impl Attribute {
|
|||
|
||||
pub fn vertex_pointer(&self, size: i32, ty: Type, normalized: bool, stride: i32, offset: i32) {
|
||||
unsafe {
|
||||
gl::VertexAttribPointer(self.0 as u32, size, ty, normalized as u8, stride, offset as *const gl::types::GLvoid);
|
||||
gl::VertexAttribPointer(self.0 as u32,
|
||||
size,
|
||||
ty,
|
||||
normalized as u8,
|
||||
stride,
|
||||
offset as *const gl::types::GLvoid);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vertex_pointer_int(&self, size: i32, ty: Type, stride: i32, offset: i32) {
|
||||
unsafe {
|
||||
gl::VertexAttribIPointer(self.0 as u32, size, ty, stride, offset as *const gl::types::GLvoid);
|
||||
gl::VertexAttribIPointer(self.0 as u32,
|
||||
size,
|
||||
ty,
|
||||
stride,
|
||||
offset as *const gl::types::GLvoid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -426,7 +516,9 @@ impl VertexArray {
|
|||
/// Allocates a new VertexArray.
|
||||
pub fn new() -> VertexArray {
|
||||
let mut va = VertexArray(0);
|
||||
unsafe { gl::GenVertexArrays(1, &mut va.0); }
|
||||
unsafe {
|
||||
gl::GenVertexArrays(1, &mut va.0);
|
||||
}
|
||||
va
|
||||
}
|
||||
|
||||
|
@ -434,13 +526,17 @@ impl VertexArray {
|
|||
/// means buffers/the format of the buffers etc will be bound to
|
||||
/// this VertexArray.
|
||||
pub fn bind(&self) {
|
||||
unsafe { gl::BindVertexArray(self.0); }
|
||||
unsafe {
|
||||
gl::BindVertexArray(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for VertexArray {
|
||||
fn drop(&mut self) {
|
||||
unsafe { gl::DeleteVertexArrays(1, &self.0); }
|
||||
unsafe {
|
||||
gl::DeleteVertexArrays(1, &self.0);
|
||||
}
|
||||
self.0 = 0;
|
||||
}
|
||||
}
|
||||
|
@ -480,7 +576,9 @@ impl Buffer {
|
|||
/// Allocates a new Buffer.
|
||||
pub fn new() -> Buffer {
|
||||
let mut b = Buffer(0);
|
||||
unsafe { gl::GenBuffers(1, &mut b.0); }
|
||||
unsafe {
|
||||
gl::GenBuffers(1, &mut b.0);
|
||||
}
|
||||
b
|
||||
}
|
||||
|
||||
|
@ -488,12 +586,17 @@ impl Buffer {
|
|||
/// This will allow it to be the source of operations that act on a buffer
|
||||
/// (Data, Map etc).
|
||||
pub fn bind(&self, target: BufferTarget) {
|
||||
unsafe { gl::BindBuffer(target, self.0); }
|
||||
unsafe {
|
||||
gl::BindBuffer(target, self.0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_data(&self, target: BufferTarget, data: &[u8], usage: BufferUsage) {
|
||||
unsafe {
|
||||
gl::BufferData(target, data.len() as i64, data.as_ptr() as *const gl::types::GLvoid, usage);
|
||||
gl::BufferData(target,
|
||||
data.len() as i64,
|
||||
data.as_ptr() as *const gl::types::GLvoid,
|
||||
usage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,7 +609,10 @@ impl Buffer {
|
|||
/// length is valid.
|
||||
pub fn map(&self, target: BufferTarget, access: Access, length: usize) -> MappedBuffer {
|
||||
unsafe {
|
||||
MappedBuffer{inner: Vec::from_raw_parts(gl::MapBuffer(target, access) as *mut u8, 0, length), target: target}
|
||||
MappedBuffer {
|
||||
inner: Vec::from_raw_parts(gl::MapBuffer(target, access) as *mut u8, 0, length),
|
||||
target: target,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -540,7 +646,9 @@ impl DerefMut for MappedBuffer {
|
|||
|
||||
impl Drop for MappedBuffer {
|
||||
fn drop(&mut self) {
|
||||
unsafe { gl::UnmapBuffer(self.target); }
|
||||
unsafe {
|
||||
gl::UnmapBuffer(self.target);
|
||||
}
|
||||
mem::forget(mem::replace(&mut self.inner, Vec::new()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
use nbt;
|
||||
use protocol::{Serializable};
|
||||
use protocol::Serializable;
|
||||
use std::io;
|
||||
use std::io::{Read, Write};
|
||||
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
|
||||
|
@ -58,7 +58,7 @@ impl Serializable for Option<Stack> {
|
|||
try!(buf.write_u8(val.count as u8));
|
||||
try!(buf.write_i16::<BigEndian>(val.damage as i16));
|
||||
try!(val.tag.write_to(buf));
|
||||
},
|
||||
}
|
||||
None => try!(buf.write_i16::<BigEndian>(-1)),
|
||||
}
|
||||
Result::Ok(())
|
||||
|
|
45
src/main.rs
45
src/main.rs
|
@ -44,8 +44,8 @@ use std::marker::PhantomData;
|
|||
const CL_BRAND: console::CVar<String> = console::CVar {
|
||||
ty: PhantomData,
|
||||
name: "cl_brand",
|
||||
description: "cl_brand has the value of the clients current 'brand'. \
|
||||
e.g. \"Steven\" or \"Vanilla\"",
|
||||
description: "cl_brand has the value of the clients current 'brand'. e.g. \"Steven\" or \
|
||||
\"Vanilla\"",
|
||||
mutable: false,
|
||||
serializable: false,
|
||||
default: &|| "steven".to_owned(),
|
||||
|
@ -74,12 +74,15 @@ fn main() {
|
|||
log::set_logger(|max_log_level| {
|
||||
max_log_level.set(log::LogLevelFilter::Trace);
|
||||
Box::new(proxy)
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
info!("Starting steven");
|
||||
|
||||
let resource_manager = Arc::new(RwLock::new(resources::Manager::new()));
|
||||
{ resource_manager.write().unwrap().tick(); }
|
||||
{
|
||||
resource_manager.write().unwrap().tick();
|
||||
}
|
||||
|
||||
let mut window = glutin::WindowBuilder::new()
|
||||
.with_title("Steven".to_string())
|
||||
|
@ -89,7 +92,9 @@ fn main() {
|
|||
.with_depth_buffer(24)
|
||||
.with_stencil_buffer(0)
|
||||
.with_vsync()
|
||||
.build().ok().expect("Could not create Glutin window.");
|
||||
.build()
|
||||
.ok()
|
||||
.expect("Could not create Glutin window.");
|
||||
|
||||
unsafe {
|
||||
window.make_current().ok().expect("Could not set current context.");
|
||||
|
@ -116,7 +121,9 @@ fn main() {
|
|||
};
|
||||
|
||||
while !game.should_close {
|
||||
{ game.resource_manager.write().unwrap().tick(); }
|
||||
{
|
||||
game.resource_manager.write().unwrap().tick();
|
||||
}
|
||||
|
||||
let now = time::now();
|
||||
let diff = now - last_frame;
|
||||
|
@ -125,7 +132,10 @@ fn main() {
|
|||
let (width, height) = window.get_inner_size_pixels().unwrap();
|
||||
|
||||
game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container);
|
||||
game.console.lock().unwrap().tick(&mut ui_container, &mut game.renderer, delta, width as f64);
|
||||
game.console
|
||||
.lock()
|
||||
.unwrap()
|
||||
.tick(&mut ui_container, &mut game.renderer, delta, width as f64);
|
||||
ui_container.tick(&mut game.renderer, delta, width as f64, height as f64);
|
||||
game.renderer.tick(delta, width, height);
|
||||
|
||||
|
@ -137,7 +147,10 @@ fn main() {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_window_event(window: &glutin::Window, game: &mut Game, ui_container: &mut ui::Container, event: glutin::Event) {
|
||||
fn handle_window_event(window: &glutin::Window,
|
||||
game: &mut Game,
|
||||
ui_container: &mut ui::Container,
|
||||
event: glutin::Event) {
|
||||
use glutin::{Event, VirtualKeyCode};
|
||||
match event {
|
||||
Event::Closed => game.should_close = true,
|
||||
|
@ -147,34 +160,34 @@ fn handle_window_event(window: &glutin::Window, game: &mut Game, ui_container: &
|
|||
let (width, height) = window.get_inner_size_pixels().unwrap();
|
||||
|
||||
ui_container.hover_at(game, x as f64, y as f64, width as f64, height as f64);
|
||||
},
|
||||
}
|
||||
|
||||
Event::MouseInput(glutin::ElementState::Released, glutin::MouseButton::Left) => {
|
||||
let (x, y) = game.mouse_pos;
|
||||
let (width, height) = window.get_inner_size_pixels().unwrap();
|
||||
|
||||
ui_container.click_at(game, x as f64, y as f64, width as f64, height as f64);
|
||||
},
|
||||
}
|
||||
|
||||
Event::MouseWheel(delta) => {
|
||||
let (x, y) = match delta {
|
||||
glutin::MouseScrollDelta::LineDelta(x, y) => (x, y),
|
||||
glutin::MouseScrollDelta::PixelDelta(x, y) => (x, y)
|
||||
glutin::MouseScrollDelta::PixelDelta(x, y) => (x, y),
|
||||
};
|
||||
|
||||
game.screen_sys.on_scroll(x as f64, y as f64);
|
||||
},
|
||||
}
|
||||
|
||||
Event::KeyboardInput(glutin::ElementState::Pressed, 41 /* ` GRAVE */, _) => {
|
||||
game.console.lock().unwrap().toggle();
|
||||
},
|
||||
}
|
||||
Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(VirtualKeyCode::Grave)) => {
|
||||
game.console.lock().unwrap().toggle();
|
||||
},
|
||||
}
|
||||
Event::KeyboardInput(glutin::ElementState::Pressed, key, virt) => {
|
||||
println!("Key: {:?} {:?}", key, virt);
|
||||
},
|
||||
}
|
||||
|
||||
_ => ()
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::collections::HashMap;
|
|||
use std::io;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use super::protocol::{Serializable};
|
||||
use super::protocol::Serializable;
|
||||
use super::protocol;
|
||||
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
|
||||
|
||||
|
@ -196,7 +196,7 @@ impl Tag {
|
|||
l.push(try!(Tag::read_type(ty, buf)));
|
||||
}
|
||||
Ok(Tag::List(l))
|
||||
},
|
||||
}
|
||||
10 => {
|
||||
let mut c = Tag::new_compound();
|
||||
loop {
|
||||
|
@ -208,7 +208,7 @@ impl Tag {
|
|||
c.put(&name[..], try!(Tag::read_type(ty, buf)));
|
||||
}
|
||||
Ok(c)
|
||||
},
|
||||
}
|
||||
11 => Ok(Tag::IntArray({
|
||||
let len: i32 = try!(Serializable::read_from(buf));
|
||||
let mut data = Vec::with_capacity(len as usize);
|
||||
|
@ -217,7 +217,8 @@ impl Tag {
|
|||
}
|
||||
data
|
||||
})),
|
||||
_ => Err(io::Error::new(io::ErrorKind::InvalidData, protocol::Error::Err("invalid tag".to_owned()))),
|
||||
_ => Err(io::Error::new(io::ErrorKind::InvalidData,
|
||||
protocol::Error::Err("invalid tag".to_owned()))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -229,7 +230,7 @@ impl Serializable for Tag {
|
|||
|
||||
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
|
||||
match *self {
|
||||
Tag::End => {},
|
||||
Tag::End => {}
|
||||
Tag::Byte(val) => try!(buf.write_i8(val)),
|
||||
Tag::Short(val) => try!(buf.write_i16::<BigEndian>(val)),
|
||||
Tag::Int(val) => try!(buf.write_i32::<BigEndian>(val)),
|
||||
|
@ -239,7 +240,7 @@ impl Serializable for Tag {
|
|||
Tag::ByteArray(ref val) => {
|
||||
try!((val.len() as i32).write_to(buf));
|
||||
try!(buf.write_all(val));
|
||||
},
|
||||
}
|
||||
Tag::String(ref val) => try!(write_string(buf, val)),
|
||||
Tag::List(ref val) => {
|
||||
if val.is_empty() {
|
||||
|
@ -252,7 +253,7 @@ impl Serializable for Tag {
|
|||
try!(e.write_to(buf));
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Tag::Compound(ref val) => {
|
||||
for (k, v) in val {
|
||||
try!(v.internal_id().write_to(buf));
|
||||
|
@ -260,13 +261,13 @@ impl Serializable for Tag {
|
|||
try!(v.write_to(buf));
|
||||
}
|
||||
try!(buf.write_u8(0));
|
||||
},
|
||||
}
|
||||
Tag::IntArray(ref val) => {
|
||||
try!((val.len() as i32).write_to(buf));
|
||||
for v in val {
|
||||
try!(v.write_to(buf));
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Result::Ok(())
|
||||
}
|
||||
|
|
|
@ -232,7 +232,11 @@ impl Serializable for bool {
|
|||
Result::Ok(try!(buf.read_u8()) != 0)
|
||||
}
|
||||
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
|
||||
try!(buf.write_u8(if *self { 1 } else { 0 }));
|
||||
try!(buf.write_u8(if *self {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}));
|
||||
Result::Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -321,17 +325,15 @@ impl Serializable for f64 {
|
|||
pub struct UUID(u64, u64);
|
||||
|
||||
impl Default for UUID {
|
||||
fn default() -> Self { UUID(0, 0) }
|
||||
fn default() -> Self {
|
||||
UUID(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serializable for UUID {
|
||||
fn read_from(buf: &mut io::Read) -> Result<UUID, io::Error> {
|
||||
Result::Ok(
|
||||
UUID(
|
||||
try!(buf.read_u64::<BigEndian>()),
|
||||
try!(buf.read_u64::<BigEndian>()),
|
||||
)
|
||||
)
|
||||
Result::Ok(UUID(try!(buf.read_u64::<BigEndian>()),
|
||||
try!(buf.read_u64::<BigEndian>())))
|
||||
}
|
||||
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
|
||||
try!(buf.write_u64::<BigEndian>(self.0));
|
||||
|
@ -348,7 +350,7 @@ pub trait Lengthable : Serializable + Copy + Default {
|
|||
|
||||
pub struct LenPrefixed<L: Lengthable, V> {
|
||||
len: L,
|
||||
pub data: Vec<V>
|
||||
pub data: Vec<V>,
|
||||
}
|
||||
|
||||
impl <L: Lengthable, V: Default> LenPrefixed<L, V> {
|
||||
|
@ -368,7 +370,10 @@ impl <L: Lengthable, V: Serializable> Serializable for LenPrefixed<L, V> {
|
|||
for _ in 0..len {
|
||||
data.push(try!(Serializable::read_from(buf)));
|
||||
}
|
||||
Result::Ok(LenPrefixed{len: len_data, data: data})
|
||||
Result::Ok(LenPrefixed {
|
||||
len: len_data,
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
|
||||
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
|
||||
|
@ -387,7 +392,7 @@ impl <L: Lengthable, V: Default> Default for LenPrefixed<L, V> {
|
|||
fn default() -> Self {
|
||||
LenPrefixed {
|
||||
len: default::Default::default(),
|
||||
data: default::Default::default()
|
||||
data: default::Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -401,7 +406,7 @@ impl <L: Lengthable, V: fmt::Debug> fmt::Debug for LenPrefixed<L, V> {
|
|||
// Optimization
|
||||
pub struct LenPrefixedBytes<L: Lengthable> {
|
||||
len: L,
|
||||
pub data: Vec<u8>
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl <L: Lengthable> LenPrefixedBytes<L> {
|
||||
|
@ -419,7 +424,10 @@ impl <L: Lengthable> Serializable for LenPrefixedBytes<L> {
|
|||
let len: usize = len_data.into();
|
||||
let mut data: Vec<u8> = Vec::with_capacity(len);
|
||||
try!(buf.take(len as u64).read_to_end(&mut data));
|
||||
Result::Ok(LenPrefixedBytes{len: len_data, data: data})
|
||||
Result::Ok(LenPrefixedBytes {
|
||||
len: len_data,
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
|
||||
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
|
||||
|
@ -435,7 +443,7 @@ impl <L: Lengthable> Default for LenPrefixedBytes<L> {
|
|||
fn default() -> Self {
|
||||
LenPrefixedBytes {
|
||||
len: default::Default::default(),
|
||||
data: default::Default::default()
|
||||
data: default::Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -492,7 +500,8 @@ impl Serializable for VarInt {
|
|||
val |= (b & PART) << (size * 7);
|
||||
size += 1;
|
||||
if size > 5 {
|
||||
return Result::Err(io::Error::new(io::ErrorKind::InvalidInput, Error::Err("VarInt too big".to_owned())))
|
||||
return Result::Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
Error::Err("VarInt too big".to_owned())))
|
||||
}
|
||||
if (b & 0x80) == 0 {
|
||||
break
|
||||
|
@ -518,7 +527,9 @@ impl Serializable for VarInt {
|
|||
}
|
||||
|
||||
impl default::Default for VarInt {
|
||||
fn default() -> VarInt { VarInt(0) }
|
||||
fn default() -> VarInt {
|
||||
VarInt(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for VarInt {
|
||||
|
@ -553,7 +564,8 @@ impl Serializable for VarLong {
|
|||
val |= (b & PART) << (size * 7);
|
||||
size += 1;
|
||||
if size > 10 {
|
||||
return Result::Err(io::Error::new(io::ErrorKind::InvalidInput, Error::Err("VarLong too big".to_owned())))
|
||||
return Result::Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
Error::Err("VarLong too big".to_owned())))
|
||||
}
|
||||
if (b & 0x80) == 0 {
|
||||
break
|
||||
|
@ -579,7 +591,9 @@ impl Serializable for VarLong {
|
|||
}
|
||||
|
||||
impl default::Default for VarLong {
|
||||
fn default() -> VarLong { VarLong(0) }
|
||||
fn default() -> VarLong {
|
||||
VarLong(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for VarLong {
|
||||
|
@ -593,7 +607,7 @@ impl fmt::Debug for VarLong {
|
|||
#[derive(Clone, Copy)]
|
||||
pub enum Direction {
|
||||
Serverbound,
|
||||
Clientbound
|
||||
Clientbound,
|
||||
}
|
||||
|
||||
/// The protocol has multiple 'sub-protocols' or states which control which
|
||||
|
@ -603,7 +617,7 @@ pub enum State {
|
|||
Handshaking,
|
||||
Play,
|
||||
Status,
|
||||
Login
|
||||
Login,
|
||||
}
|
||||
|
||||
/// Return for any protocol related error.
|
||||
|
@ -632,7 +646,7 @@ impl ::std::fmt::Display for Error {
|
|||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match *self {
|
||||
Error::Err(ref val) => write!(f, "protocol error: {}", val),
|
||||
Error::IOError(ref e) => e.fmt(f)
|
||||
Error::IOError(ref e) => e.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -680,7 +694,11 @@ impl Conn {
|
|||
try!(VarInt(packet.packet_id()).write_to(&mut buf));
|
||||
try!(packet.write(&mut buf));
|
||||
|
||||
let mut extra = if self.compression_threshold >= 0 { 1 } else { 0 };
|
||||
let mut extra = if self.compression_threshold >= 0 {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
if self.compression_threshold >= 0 && buf.len() as i32 > self.compression_threshold {
|
||||
extra = 0;
|
||||
let uncompressed_size = buf.len();
|
||||
|
@ -734,11 +752,14 @@ impl Conn {
|
|||
let pos = buf.position() as usize;
|
||||
let ibuf = buf.into_inner();
|
||||
if ibuf.len() != pos {
|
||||
return Result::Err(Error::Err(format!("Failed to read all of packet 0x{:X}, had {} bytes left", id, ibuf.len() - pos)))
|
||||
return Result::Err(Error::Err(format!("Failed to read all of packet 0x{:X}, \
|
||||
had {} bytes left",
|
||||
id,
|
||||
ibuf.len() - pos)))
|
||||
}
|
||||
Result::Ok(val)
|
||||
},
|
||||
None => Result::Err(Error::Err("missing packet".to_owned()))
|
||||
}
|
||||
None => Result::Err(Error::Err("missing packet".to_owned())),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -749,7 +770,8 @@ impl Conn {
|
|||
pub fn set_compresssion(&mut self, threshold: i32, read: bool) {
|
||||
self.compression_threshold = threshold;
|
||||
if !read {
|
||||
self.compression_write = Some(ZlibEncoder::new(io::Cursor::new(Vec::new()), flate2::Compression::Default));
|
||||
self.compression_write = Some(ZlibEncoder::new(io::Cursor::new(Vec::new()),
|
||||
flate2::Compression::Default));
|
||||
} else {
|
||||
self.compression_read = Some(ZlibDecoder::new(io::Cursor::new(Vec::new())));
|
||||
}
|
||||
|
@ -800,17 +822,26 @@ impl Conn {
|
|||
|
||||
Ok((Status {
|
||||
version: StatusVersion {
|
||||
name: try!(version.find("name").and_then(Value::as_string).ok_or(invalid_status())).to_owned(),
|
||||
protocol: try!(version.find("protocol").and_then(Value::as_i64).ok_or(invalid_status())) as i32,
|
||||
name: try!(version.find("name").and_then(Value::as_string).ok_or(invalid_status()))
|
||||
.to_owned(),
|
||||
protocol: try!(version.find("protocol")
|
||||
.and_then(Value::as_i64)
|
||||
.ok_or(invalid_status())) as i32,
|
||||
},
|
||||
players: StatusPlayers {
|
||||
max: try!(players.find("max").and_then(Value::as_i64).ok_or(invalid_status())) as i32,
|
||||
online: try!(players.find("online").and_then(Value::as_i64).ok_or(invalid_status())) as i32,
|
||||
sample: Vec::new(), // TODO
|
||||
max: try!(players.find("max")
|
||||
.and_then(Value::as_i64)
|
||||
.ok_or(invalid_status())) as i32,
|
||||
online: try!(players.find("online")
|
||||
.and_then(Value::as_i64)
|
||||
.ok_or(invalid_status())) as i32,
|
||||
sample: Vec::new(), /* TODO */
|
||||
},
|
||||
description: format::Component::from_value(try!(val.find("description").ok_or(invalid_status()))),
|
||||
description: format::Component::from_value(try!(val.find("description")
|
||||
.ok_or(invalid_status()))),
|
||||
favicon: val.find("favicon").and_then(Value::as_string).map(|v| v.to_owned()),
|
||||
}, ping))
|
||||
},
|
||||
ping))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -852,7 +883,7 @@ impl Read for Conn {
|
|||
buf[i] = data[i];
|
||||
}
|
||||
Ok(ret)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -865,7 +896,7 @@ impl Write for Conn {
|
|||
let data = cipher.encrypt(buf);
|
||||
try!(self.stream.write_all(&data[..]));
|
||||
Ok(buf.len())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -906,9 +937,11 @@ pub fn test() {
|
|||
host: "localhost".to_owned(),
|
||||
port: 25565,
|
||||
next: VarInt(2),
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
c.state = State::Login;
|
||||
c.write_packet(packet::login::serverbound::LoginStart{username: "Think".to_owned()}).unwrap();
|
||||
c.write_packet(packet::login::serverbound::LoginStart { username: "Think".to_owned() })
|
||||
.unwrap();
|
||||
|
||||
let packet = match c.read_packet().unwrap() {
|
||||
packet::Packet::EncryptionRequest(val) => val,
|
||||
|
@ -924,7 +957,7 @@ pub fn test() {
|
|||
let profile = mojang::Profile {
|
||||
username: "Think".to_owned(),
|
||||
id: "b1184d43168441cfa2128b9a3df3b6ab".to_owned(),
|
||||
access_token: "".to_owned()
|
||||
access_token: "".to_owned(),
|
||||
};
|
||||
|
||||
profile.join_server(&packet.server_id, &shared, &packet.public_key.data);
|
||||
|
@ -932,7 +965,8 @@ pub fn test() {
|
|||
c.write_packet(packet::login::serverbound::EncryptionResponse {
|
||||
shared_secret: LenPrefixedBytes::new(shared_e),
|
||||
verify_token: LenPrefixedBytes::new(token_e),
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let mut read = c.clone();
|
||||
let mut write = c.clone();
|
||||
|
@ -940,15 +974,16 @@ pub fn test() {
|
|||
read.enable_encyption(&shared, true);
|
||||
write.enable_encyption(&shared, false);
|
||||
|
||||
loop { match read.read_packet().unwrap() {
|
||||
loop {
|
||||
match read.read_packet().unwrap() {
|
||||
packet::Packet::LoginDisconnect(val) => {
|
||||
panic!("Discconect {}", val.reason);
|
||||
},
|
||||
}
|
||||
packet::Packet::SetInitialCompression(val) => {
|
||||
read.set_compresssion(val.threshold.0, true);
|
||||
write.set_compresssion(val.threshold.0, false);
|
||||
println!("Compression: {}", val.threshold.0)
|
||||
},
|
||||
}
|
||||
packet::Packet::LoginSuccess(val) => {
|
||||
println!("Login: {} {}", val.username, val.uuid);
|
||||
read.state = State::Play;
|
||||
|
@ -956,19 +991,22 @@ pub fn test() {
|
|||
break;
|
||||
}
|
||||
_ => panic!("Unknown packet"),
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
let mut first = true;
|
||||
let mut count = 0;
|
||||
loop { match read.read_packet().unwrap() {
|
||||
loop {
|
||||
match read.read_packet().unwrap() {
|
||||
packet::Packet::ServerMessage(val) => println!("MSG: {}", val.message),
|
||||
packet::Packet::ChunkData(_) => {},
|
||||
packet::Packet::ChunkData(_) => {}
|
||||
val => {
|
||||
println!("{:?}", val);
|
||||
if first {
|
||||
write.write_packet(packet::play::serverbound::ChatMessage {
|
||||
message: "Hello world".to_owned(),
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
first = false;
|
||||
}
|
||||
count += 1;
|
||||
|
@ -976,7 +1014,8 @@ pub fn test() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
unimplemented!();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ use hyper;
|
|||
pub struct Profile {
|
||||
pub username: String,
|
||||
pub id: String,
|
||||
pub access_token: String
|
||||
pub access_token: String,
|
||||
}
|
||||
|
||||
const JOIN_URL: &'static str = "https://sessionserver.mojang.com/session/minecraft/join";
|
||||
|
@ -57,7 +57,8 @@ impl Profile {
|
|||
let res = client.post(JOIN_URL)
|
||||
.body(&join)
|
||||
.header(hyper::header::ContentType("application/json".parse().unwrap()))
|
||||
.send().unwrap();
|
||||
.send()
|
||||
.unwrap();
|
||||
|
||||
let ret: serde_json::Value = match serde_json::from_reader(res) {
|
||||
Result::Ok(val) => val,
|
||||
|
|
|
@ -91,7 +91,7 @@ state_packets!(
|
|||
button: u8 =,
|
||||
action_number: u16 =,
|
||||
mode: u8 =,
|
||||
clicked_item: Option<item::Stack> =, // TODO
|
||||
clicked_item: Option<item::Stack> =,
|
||||
}
|
||||
// CloseWindow is sent when the client closes a window.
|
||||
CloseWindow => 0x07 {
|
||||
|
@ -1098,19 +1098,19 @@ impl Serializable for PlayerInfoData {
|
|||
},
|
||||
};
|
||||
m.players.push(p);
|
||||
},
|
||||
}
|
||||
1 => {
|
||||
m.players.push(PlayerDetail::UpdateGamemode {
|
||||
uuid: uuid,
|
||||
gamemode: try!(Serializable::read_from(buf)),
|
||||
})
|
||||
},
|
||||
}
|
||||
2 => {
|
||||
m.players.push(PlayerDetail::UpdateLatency {
|
||||
uuid: uuid,
|
||||
ping: try!(Serializable::read_from(buf)),
|
||||
})
|
||||
},
|
||||
}
|
||||
3 => {
|
||||
m.players.push(PlayerDetail::UpdateDisplayName {
|
||||
uuid: uuid,
|
||||
|
@ -1122,12 +1122,10 @@ impl Serializable for PlayerInfoData {
|
|||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
4 => {
|
||||
m.players.push(PlayerDetail::Remove{
|
||||
uuid: uuid,
|
||||
})
|
||||
},
|
||||
m.players.push(PlayerDetail::Remove { uuid: uuid })
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
@ -1150,11 +1148,29 @@ impl Default for PlayerInfoData {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub enum PlayerDetail {
|
||||
Add{uuid: UUID, name: String, properties: Vec<PlayerProperty>, gamemode: VarInt, ping: VarInt, display: Option<format::Component>},
|
||||
UpdateGamemode{uuid: UUID, gamemode: VarInt},
|
||||
UpdateLatency{uuid: UUID, ping: VarInt},
|
||||
UpdateDisplayName{uuid: UUID, display: Option<format::Component>},
|
||||
Remove{uuid: UUID},
|
||||
Add {
|
||||
uuid: UUID,
|
||||
name: String,
|
||||
properties: Vec<PlayerProperty>,
|
||||
gamemode: VarInt,
|
||||
ping: VarInt,
|
||||
display: Option<format::Component>,
|
||||
},
|
||||
UpdateGamemode {
|
||||
uuid: UUID,
|
||||
gamemode: VarInt,
|
||||
},
|
||||
UpdateLatency {
|
||||
uuid: UUID,
|
||||
ping: VarInt,
|
||||
},
|
||||
UpdateDisplayName {
|
||||
uuid: UUID,
|
||||
display: Option<format::Component>,
|
||||
},
|
||||
Remove {
|
||||
uuid: UUID,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -26,12 +26,12 @@ pub struct Rect {
|
|||
|
||||
impl Atlas {
|
||||
pub fn new(width: usize, height: usize) -> Atlas {
|
||||
let mut a = Atlas {
|
||||
free_space: Vec::new(),
|
||||
};
|
||||
let mut a = Atlas { free_space: Vec::new() };
|
||||
a.free_space.push(Rect {
|
||||
x: 0, y: 0,
|
||||
width: width, height: height,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: width,
|
||||
height: height,
|
||||
});
|
||||
a
|
||||
}
|
||||
|
@ -60,8 +60,10 @@ impl Atlas {
|
|||
}
|
||||
let mut t = target.unwrap();
|
||||
let ret = Rect {
|
||||
x: t.x, y: t.y,
|
||||
width: width, height: height,
|
||||
x: t.x,
|
||||
y: t.y,
|
||||
width: width,
|
||||
height: height,
|
||||
};
|
||||
|
||||
if width == t.width {
|
||||
|
@ -76,9 +78,12 @@ impl Atlas {
|
|||
} else {
|
||||
if t.height > height {
|
||||
// Split by height
|
||||
self.free_space.insert(0, Rect{
|
||||
x: t.x, y: t.y + height,
|
||||
width: width, height: t.height - height,
|
||||
self.free_space.insert(0,
|
||||
Rect {
|
||||
x: t.x,
|
||||
y: t.y + height,
|
||||
width: width,
|
||||
height: t.height - height,
|
||||
});
|
||||
target_index += 1;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,7 @@ pub struct Registry {
|
|||
|
||||
impl Registry {
|
||||
pub fn new() -> Registry {
|
||||
Registry {
|
||||
shaders: HashMap::new(),
|
||||
}
|
||||
Registry { shaders: HashMap::new() }
|
||||
}
|
||||
|
||||
pub fn register(&mut self, name: &str, source: &str) {
|
||||
|
|
|
@ -23,7 +23,7 @@ use std::sync::{Arc, RwLock};
|
|||
use resources;
|
||||
use gl;
|
||||
use image;
|
||||
use image::{GenericImage};
|
||||
use image::GenericImage;
|
||||
use byteorder::{WriteBytesExt, NativeEndian};
|
||||
use serde_json;
|
||||
|
||||
|
@ -44,10 +44,19 @@ pub struct Renderer {
|
|||
|
||||
impl Renderer {
|
||||
pub fn new(res: Arc<RwLock<resources::Manager>>) -> Renderer {
|
||||
let version = { res.read().unwrap().version() };
|
||||
let version = {
|
||||
res.read().unwrap().version()
|
||||
};
|
||||
let tex = gl::Texture::new();
|
||||
tex.bind(gl::TEXTURE_2D_ARRAY);
|
||||
tex.image_3d(gl::TEXTURE_2D_ARRAY, 0, ATLAS_SIZE as u32, ATLAS_SIZE as u32, 1, gl::RGBA, gl::UNSIGNED_BYTE, &[0; ATLAS_SIZE*ATLAS_SIZE*4]);
|
||||
tex.image_3d(gl::TEXTURE_2D_ARRAY,
|
||||
0,
|
||||
ATLAS_SIZE as u32,
|
||||
ATLAS_SIZE as u32,
|
||||
1,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
&[0; ATLAS_SIZE * ATLAS_SIZE * 4]);
|
||||
tex.set_parameter(gl::TEXTURE_2D_ARRAY, gl::TEXTURE_MAG_FILTER, gl::NEAREST);
|
||||
tex.set_parameter(gl::TEXTURE_2D_ARRAY, gl::TEXTURE_MIN_FILTER, gl::NEAREST);
|
||||
tex.set_parameter(gl::TEXTURE_2D_ARRAY, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE);
|
||||
|
@ -119,9 +128,22 @@ impl Renderer {
|
|||
if self.texture_layers != tex.atlases.len() {
|
||||
let len = ATLAS_SIZE * ATLAS_SIZE * 4 * tex.atlases.len();
|
||||
let mut data = Vec::with_capacity(len);
|
||||
unsafe { data.set_len(len); }
|
||||
self.gl_texture.get_pixels(gl::TEXTURE_2D_ARRAY, 0, gl::RGBA, gl::UNSIGNED_BYTE, &mut data[..]);
|
||||
self.gl_texture.image_3d(gl::TEXTURE_2D_ARRAY, 0, ATLAS_SIZE as u32, ATLAS_SIZE as u32, tex.atlases.len() as u32, gl::RGBA, gl::UNSIGNED_BYTE, &data[..]);
|
||||
unsafe {
|
||||
data.set_len(len);
|
||||
}
|
||||
self.gl_texture.get_pixels(gl::TEXTURE_2D_ARRAY,
|
||||
0,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
&mut data[..]);
|
||||
self.gl_texture.image_3d(gl::TEXTURE_2D_ARRAY,
|
||||
0,
|
||||
ATLAS_SIZE as u32,
|
||||
ATLAS_SIZE as u32,
|
||||
tex.atlases.len() as u32,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
&data[..]);
|
||||
self.texture_layers = tex.atlases.len();
|
||||
}
|
||||
tex.pending_uploads.len()
|
||||
|
@ -132,7 +154,17 @@ impl Renderer {
|
|||
let atlas = upload.0;
|
||||
let rect = upload.1;
|
||||
let img = &upload.2;
|
||||
self.gl_texture.sub_image_3d(gl::TEXTURE_2D_ARRAY, 0, rect.x as u32, rect.y as u32, atlas as u32, rect.width as u32, rect.height as u32, 1, gl::RGBA, gl::UNSIGNED_BYTE, &img[..]);
|
||||
self.gl_texture.sub_image_3d(gl::TEXTURE_2D_ARRAY,
|
||||
0,
|
||||
rect.x as u32,
|
||||
rect.y as u32,
|
||||
atlas as u32,
|
||||
rect.width as u32,
|
||||
rect.height as u32,
|
||||
1,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
&img[..]);
|
||||
}
|
||||
tex.pending_uploads.clear();
|
||||
}
|
||||
|
@ -141,15 +173,20 @@ impl Renderer {
|
|||
if ani.remaining_time <= 0.0 {
|
||||
ani.current_frame = (ani.current_frame + 1) % ani.frames.len();
|
||||
ani.remaining_time += ani.frames[ani.current_frame].time as f64;
|
||||
let offset = ani.texture.width * ani.texture.width * ani.frames[ani.current_frame].index * 4;
|
||||
let offset = ani.texture.width * ani.texture.width *
|
||||
ani.frames[ani.current_frame].index * 4;
|
||||
let offset2 = offset + ani.texture.width * ani.texture.width * 4;
|
||||
self.gl_texture.sub_image_3d(gl::TEXTURE_2D_ARRAY,
|
||||
0,
|
||||
ani.texture.get_x() as u32, ani.texture.get_y() as u32, ani.texture.atlas as u32,
|
||||
ani.texture.get_width() as u32, ani.texture.get_height() as u32, 1,
|
||||
gl::RGBA, gl::UNSIGNED_BYTE,
|
||||
&ani.data[offset .. offset2]
|
||||
);
|
||||
ani.texture.get_x() as u32,
|
||||
ani.texture.get_y() as u32,
|
||||
ani.texture.atlas as u32,
|
||||
ani.texture.get_width() as u32,
|
||||
ani.texture.get_height() as u32,
|
||||
1,
|
||||
gl::RGBA,
|
||||
gl::UNSIGNED_BYTE,
|
||||
&ani.data[offset..offset2]);
|
||||
} else {
|
||||
ani.remaining_time -= delta / 3.0;
|
||||
}
|
||||
|
@ -180,7 +217,9 @@ impl Renderer {
|
|||
}
|
||||
|
||||
pub fn get_texture(textures: &RwLock<TextureManager>, name: &str) -> Texture {
|
||||
let tex = { textures.read().unwrap().get_texture(name) };
|
||||
let tex = {
|
||||
textures.read().unwrap().get_texture(name)
|
||||
};
|
||||
match tex {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
|
@ -229,13 +268,21 @@ impl TextureManager {
|
|||
}
|
||||
|
||||
fn add_defaults(&mut self) {
|
||||
self.put_texture("steven", "missing_texture", 2, 2, vec![
|
||||
self.put_texture("steven",
|
||||
"missing_texture",
|
||||
2,
|
||||
2,
|
||||
vec![
|
||||
0, 0, 0, 255,
|
||||
255, 0, 255, 255,
|
||||
255, 0, 255, 255,
|
||||
0, 0, 0, 255,
|
||||
]);
|
||||
self.put_texture("steven", "solid", 1, 1, vec![
|
||||
self.put_texture("steven",
|
||||
"solid",
|
||||
1,
|
||||
1,
|
||||
vec![
|
||||
255, 255, 255, 255,
|
||||
]);
|
||||
}
|
||||
|
@ -277,9 +324,7 @@ impl TextureManager {
|
|||
// Might be animated
|
||||
if (name.starts_with("blocks/") || name.starts_with("items/")) && width != height {
|
||||
let id = img.to_rgba().into_vec();
|
||||
let frame = id[
|
||||
.. (width*width*4) as usize
|
||||
].to_owned();
|
||||
let frame = id[..(width * width * 4) as usize].to_owned();
|
||||
if let Some(mut ani) = self.load_animation(plugin, name, &img, id) {
|
||||
ani.texture = self.put_texture(plugin, name, width, width, frame);
|
||||
self.animated_textures.push(ani);
|
||||
|
@ -293,15 +338,23 @@ impl TextureManager {
|
|||
self.insert_texture_dummy(plugin, name);
|
||||
}
|
||||
|
||||
fn load_animation(&mut self, plugin: &str, name: &str, img: &image::DynamicImage, data: Vec<u8>) -> Option<AnimatedTexture> {
|
||||
fn load_animation(&mut self,
|
||||
plugin: &str,
|
||||
name: &str,
|
||||
img: &image::DynamicImage,
|
||||
data: Vec<u8>)
|
||||
-> Option<AnimatedTexture> {
|
||||
let path = format!("textures/{}.png.mcmeta", name);
|
||||
let res = self.resources.clone();
|
||||
if let Some(val) = res.read().unwrap().open(plugin, &path) {
|
||||
let meta: serde_json::Value = serde_json::from_reader(val).unwrap();
|
||||
let animation = meta.find("animation").unwrap();
|
||||
let frame_time = animation.find("frameTime").and_then(|v| v.as_i64()).unwrap_or(1);
|
||||
let interpolate = animation.find("interpolate").and_then(|v| v.as_boolean()).unwrap_or(false);
|
||||
let frames = if let Some(frames) = animation.find("frames").and_then(|v| v.as_array()) {
|
||||
let interpolate = animation.find("interpolate")
|
||||
.and_then(|v| v.as_boolean())
|
||||
.unwrap_or(false);
|
||||
let frames = if let Some(frames) = animation.find("frames")
|
||||
.and_then(|v| v.as_array()) {
|
||||
let mut out = Vec::with_capacity(frames.len());
|
||||
for frame in frames {
|
||||
if let Some(index) = frame.as_i64() {
|
||||
|
@ -342,7 +395,13 @@ impl TextureManager {
|
|||
None
|
||||
}
|
||||
|
||||
fn put_texture(&mut self, plugin: &str, name: &str, width: u32, height: u32, data: Vec<u8>) -> Texture {
|
||||
fn put_texture(&mut self,
|
||||
plugin: &str,
|
||||
name: &str,
|
||||
width: u32,
|
||||
height: u32,
|
||||
data: Vec<u8>)
|
||||
-> Texture {
|
||||
let (atlas, rect) = self.find_free(width as usize, height as usize);
|
||||
self.pending_uploads.push((atlas, rect, data));
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ use render::glsl;
|
|||
use gl;
|
||||
|
||||
pub fn add_shaders(reg: &mut glsl::Registry) {
|
||||
reg.register("lookup_texture", include_str!("shaders/lookup_texture.glsl"));
|
||||
reg.register("lookup_texture",
|
||||
include_str!("shaders/lookup_texture.glsl"));
|
||||
reg.register("get_light", include_str!("shaders/get_light.glsl"));
|
||||
|
||||
reg.register("ui_vertex", include_str!("shaders/ui_vertex.glsl"));
|
||||
|
|
132
src/render/ui.rs
132
src/render/ui.rs
|
@ -22,7 +22,7 @@ use render::glsl;
|
|||
use render::shaders;
|
||||
use byteorder::{WriteBytesExt, NativeEndian};
|
||||
use image;
|
||||
use image::{GenericImage};
|
||||
use image::GenericImage;
|
||||
|
||||
const UI_WIDTH: f64 = 854.0;
|
||||
const UI_HEIGHT: f64 = 480.0;
|
||||
|
@ -70,7 +70,10 @@ init_shader! {
|
|||
}
|
||||
|
||||
impl UIState {
|
||||
pub fn new(glsl: &glsl::Registry, textures: Arc<RwLock<render::TextureManager>>, res: Arc<RwLock<resources::Manager>>) -> UIState {
|
||||
pub fn new(glsl: &glsl::Registry,
|
||||
textures: Arc<RwLock<render::TextureManager>>,
|
||||
res: Arc<RwLock<resources::Manager>>)
|
||||
-> UIState {
|
||||
let shader = UIShader::new(glsl);
|
||||
|
||||
let array = gl::VertexArray::new();
|
||||
|
@ -95,7 +98,11 @@ impl UIState {
|
|||
}
|
||||
|
||||
let mut char_map = HashMap::new();
|
||||
let ascii_chars = "ÀÁÂÈÊËÍÓÔÕÚßãõğİıŒœŞşŴŵžȇ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αβΓπΣσμτΦΘΩδ∞∅∈∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■";
|
||||
let ascii_chars = "ÀÁÂÈÊËÍÓÔÕÚßãõğİıŒœŞşŴŵžȇ \
|
||||
!\"#$%&'()*+,-./0123456789:;\
|
||||
<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ \
|
||||
ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø׃áíóúñѪº¿®¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞\
|
||||
╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αβΓπΣσμτΦΘΩδ∞∅∈∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■";
|
||||
for (pos, c) in ascii_chars.chars().enumerate() {
|
||||
char_map.insert(c, ::std::char::from_u32(pos as u32).unwrap());
|
||||
}
|
||||
|
@ -204,19 +211,15 @@ impl UIState {
|
|||
if page == 0 {
|
||||
let sw = (self.page_width / 16.0) as u32;
|
||||
let sh = (self.page_height / 16.0) as u32;
|
||||
return p.relative(
|
||||
(cx * sw + info.0 as u32) as f32 / (self.page_width as f32),
|
||||
return p.relative((cx * sw + info.0 as u32) as f32 / (self.page_width as f32),
|
||||
(cy * sh) as f32 / (self.page_height as f32),
|
||||
(info.1 - info.0) as f32 / (self.page_width as f32),
|
||||
(sh as f32) / (self.page_height as f32)
|
||||
)
|
||||
(sh as f32) / (self.page_height as f32))
|
||||
}
|
||||
p.relative(
|
||||
(cx * 16 + info.0 as u32) as f32 / 256.0,
|
||||
p.relative((cx * 16 + info.0 as u32) as f32 / 256.0,
|
||||
(cy * 16) as f32 / 256.0,
|
||||
(info.1 - info.0) as f32 / 256.0,
|
||||
16.0 / 256.0
|
||||
)
|
||||
16.0 / 256.0)
|
||||
}
|
||||
|
||||
pub fn size_of_string(&self, val: &str) -> f64 {
|
||||
|
@ -295,15 +298,44 @@ impl UIState {
|
|||
self.new_text_scaled(val, x, y, 1.0, 1.0, r, g, b)
|
||||
}
|
||||
|
||||
pub fn new_text_scaled(&mut self, val: &str, x: f64, y: f64, sx: f64, sy: f64, r: u8, g: u8, b: u8) -> UIText {
|
||||
pub fn new_text_scaled(&mut self,
|
||||
val: &str,
|
||||
x: f64,
|
||||
y: f64,
|
||||
sx: f64,
|
||||
sy: f64,
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8)
|
||||
-> UIText {
|
||||
self.create_text(val, x, y, sx, sy, 0.0, r, g, b)
|
||||
}
|
||||
|
||||
pub fn new_text_rotated(&mut self, val: &str, x: f64, y: f64, sx: f64, sy: f64, rotation: f64, r: u8, g: u8, b: u8) -> UIText {
|
||||
pub fn new_text_rotated(&mut self,
|
||||
val: &str,
|
||||
x: f64,
|
||||
y: f64,
|
||||
sx: f64,
|
||||
sy: f64,
|
||||
rotation: f64,
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8)
|
||||
-> UIText {
|
||||
self.create_text(val, x, y, sx, sy, rotation, r, g, b)
|
||||
}
|
||||
|
||||
fn create_text(&mut self, val: &str, x: f64, y: f64, sx: f64, sy: f64, rotation: f64, r: u8, g: u8, b: u8) -> UIText {
|
||||
fn create_text(&mut self,
|
||||
val: &str,
|
||||
x: f64,
|
||||
y: f64,
|
||||
sx: f64,
|
||||
sy: f64,
|
||||
rotation: f64,
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8)
|
||||
-> UIText {
|
||||
let mut elements = Vec::new();
|
||||
let mut offset = 0.0;
|
||||
for ch in val.chars() {
|
||||
|
@ -331,14 +363,30 @@ impl UIState {
|
|||
dy = (16.0 * 0.5) + (tmpy * c + tmpx * s);
|
||||
}
|
||||
|
||||
let mut shadow = UIElement::new(&texture, x+dsx*sx, y+dsy*sy, w*sx, 16.0*sy, 0.0, 0.0, 1.0, 1.0);
|
||||
let mut shadow = UIElement::new(&texture,
|
||||
x + dsx * sx,
|
||||
y + dsy * sy,
|
||||
w * sx,
|
||||
16.0 * sy,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0);
|
||||
shadow.r = ((r as f64) * 0.25) as u8;
|
||||
shadow.g = ((g as f64) * 0.25) as u8;
|
||||
shadow.b = ((b as f64) * 0.25) as u8;
|
||||
shadow.rotation = rotation;
|
||||
elements.push(shadow);
|
||||
|
||||
let mut text = UIElement::new(&texture, x+dx*sx, y+dy*sy, w*sx, 16.0*sy, 0.0, 0.0, 1.0, 1.0);
|
||||
let mut text = UIElement::new(&texture,
|
||||
x + dx * sx,
|
||||
y + dy * sy,
|
||||
w * sx,
|
||||
16.0 * sy,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0);
|
||||
text.r = r;
|
||||
text.g = g;
|
||||
text.b = b;
|
||||
|
@ -391,7 +439,16 @@ pub struct UIElement {
|
|||
}
|
||||
|
||||
impl UIElement {
|
||||
pub fn new(tex: &render::Texture, x: f64, y: f64, width: f64, height: f64, tx: f64, ty: f64, tw: f64, th: f64) -> UIElement {
|
||||
pub fn new(tex: &render::Texture,
|
||||
x: f64,
|
||||
y: f64,
|
||||
width: f64,
|
||||
height: f64,
|
||||
tx: f64,
|
||||
ty: f64,
|
||||
tw: f64,
|
||||
th: f64)
|
||||
-> UIElement {
|
||||
let twidth = tex.get_width();
|
||||
let theight = tex.get_height();
|
||||
UIElement {
|
||||
|
@ -419,15 +476,46 @@ impl UIElement {
|
|||
|
||||
pub fn bytes(&self, width: f64, height: f64) -> Vec<u8> {
|
||||
let mut buf = Vec::with_capacity(28 * 4);
|
||||
self.append_vertex(&mut buf, self.x, self.y, self.t_offsetx, self.t_offsety, width, height);
|
||||
self.append_vertex(&mut buf, self.x + self.w, self.y, self.t_offsetx + self.t_sizew, self.t_offsety, width, height);
|
||||
self.append_vertex(&mut buf, self.x, self.y + self.h, self.t_offsetx, self.t_offsety + self.t_sizeh, width, height);
|
||||
self.append_vertex(&mut buf, self.x + self.w, self.y + self.h, self.t_offsetx + self.t_sizew, self.t_offsety + self.t_sizeh, width, height);
|
||||
self.append_vertex(&mut buf,
|
||||
self.x,
|
||||
self.y,
|
||||
self.t_offsetx,
|
||||
self.t_offsety,
|
||||
width,
|
||||
height);
|
||||
self.append_vertex(&mut buf,
|
||||
self.x + self.w,
|
||||
self.y,
|
||||
self.t_offsetx + self.t_sizew,
|
||||
self.t_offsety,
|
||||
width,
|
||||
height);
|
||||
self.append_vertex(&mut buf,
|
||||
self.x,
|
||||
self.y + self.h,
|
||||
self.t_offsetx,
|
||||
self.t_offsety + self.t_sizeh,
|
||||
width,
|
||||
height);
|
||||
self.append_vertex(&mut buf,
|
||||
self.x + self.w,
|
||||
self.y + self.h,
|
||||
self.t_offsetx + self.t_sizew,
|
||||
self.t_offsety + self.t_sizeh,
|
||||
width,
|
||||
height);
|
||||
buf
|
||||
}
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
pub fn append_vertex(&self, buf: &mut Vec<u8>, x: f64, y: f64, tx: i16, ty: i16, width: f64, height: f64) {
|
||||
pub fn append_vertex(&self,
|
||||
buf: &mut Vec<u8>,
|
||||
x: f64,
|
||||
y: f64,
|
||||
tx: i16,
|
||||
ty: i16,
|
||||
width: f64,
|
||||
height: f64) {
|
||||
let mut dx = x as f64;
|
||||
let mut dy = y as f64;
|
||||
if self.rotation != 0.0 {
|
||||
|
|
|
@ -61,7 +61,7 @@ impl Manager {
|
|||
let path = format!("assets/{}/{}", plugin, name);
|
||||
match pack.open(&path) {
|
||||
Some(val) => return Some(val),
|
||||
None => {},
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -73,7 +73,7 @@ impl Manager {
|
|||
let path = format!("assets/{}/{}", plugin, name);
|
||||
match pack.open(&path) {
|
||||
Some(val) => ret.push(val),
|
||||
None => {},
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
ret
|
||||
|
@ -102,9 +102,7 @@ impl Manager {
|
|||
fn load_vanilla(&mut self) {
|
||||
let loc = format!("./resources-{}", RESOURCES_VERSION);
|
||||
let location = path::Path::new(&loc);
|
||||
self.add_pack(Box::new(DirPack{
|
||||
root: location.to_path_buf(),
|
||||
}))
|
||||
self.add_pack(Box::new(DirPack { root: location.to_path_buf() }))
|
||||
}
|
||||
|
||||
fn download_vanilla(&mut self) {
|
||||
|
@ -120,9 +118,11 @@ impl Manager {
|
|||
println!("Vanilla assets missing, obtaining");
|
||||
thread::spawn(move || {
|
||||
let client = hyper::Client::new();
|
||||
let url = format!("https://s3.amazonaws.com/Minecraft.Download/versions/{0}/{0}.jar", RESOURCES_VERSION);
|
||||
let url = format!("https://s3.amazonaws.com/Minecraft.Download/versions/{0}/{0}.jar",
|
||||
RESOURCES_VERSION);
|
||||
let res = client.get(&url)
|
||||
.send().unwrap();
|
||||
.send()
|
||||
.unwrap();
|
||||
let mut file = fs::File::create(format!("{}.tmp", RESOURCES_VERSION)).unwrap();
|
||||
|
||||
let length = *res.headers.get::<hyper::header::ContentLength>().unwrap();
|
||||
|
@ -194,7 +194,8 @@ impl <T: io::Read> io::Read for ProgressRead<T> {
|
|||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let size = try!(self.read.read(buf));
|
||||
self.progress += size as u64;
|
||||
println!("Progress: {:.2}", (self.progress as f64) / (self.total as f64));
|
||||
println!("Progress: {:.2}",
|
||||
(self.progress as f64) / (self.total as f64));
|
||||
Ok(size)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,7 @@ struct UIElements {
|
|||
|
||||
impl Login {
|
||||
pub fn new() -> Login {
|
||||
Login {
|
||||
elements: None,
|
||||
}
|
||||
Login { elements: None }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,20 +39,35 @@ impl super::Screen for Login {
|
|||
let mut elements = ui::Collection::new();
|
||||
|
||||
// Login
|
||||
let (mut login, mut txt) = super::new_button_text(renderer, "Login", 0.0, 100.0, 400.0, 40.0);
|
||||
let (mut login, mut txt) = super::new_button_text(renderer,
|
||||
"Login",
|
||||
0.0,
|
||||
100.0,
|
||||
400.0,
|
||||
40.0);
|
||||
login.set_v_attach(ui::VAttach::Middle);
|
||||
login.set_h_attach(ui::HAttach::Center);
|
||||
let re = ui_container.add(login);
|
||||
txt.set_parent(&re);
|
||||
let tre = ui_container.add(txt);
|
||||
super::button_action(ui_container, re.clone(), Some(tre.clone()), Some(Rc::new(|game, _| {
|
||||
game.screen_sys.replace_screen(Box::new(super::ServerList::new(None)));
|
||||
super::button_action(ui_container,
|
||||
re.clone(),
|
||||
Some(tre.clone()),
|
||||
Some(Rc::new(|game, _| {
|
||||
game.screen_sys
|
||||
.replace_screen(Box::new(super::ServerList::new(None)));
|
||||
})));
|
||||
elements.add(re);
|
||||
elements.add(tre);
|
||||
|
||||
// Disclaimer
|
||||
let mut warn = ui::Text::new(renderer, "Not affiliated with Mojang/Minecraft", 5.0, 5.0, 255, 200, 200);
|
||||
let mut warn = ui::Text::new(renderer,
|
||||
"Not affiliated with Mojang/Minecraft",
|
||||
5.0,
|
||||
5.0,
|
||||
255,
|
||||
200,
|
||||
200);
|
||||
warn.set_v_attach(ui::VAttach::Bottom);
|
||||
warn.set_h_attach(ui::HAttach::Right);
|
||||
elements.add(ui_container.add(warn));
|
||||
|
@ -74,7 +87,10 @@ impl super::Screen for Login {
|
|||
self.elements = None
|
||||
}
|
||||
|
||||
fn tick(&mut self, delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
fn tick(&mut self,
|
||||
delta: f64,
|
||||
renderer: &mut render::Renderer,
|
||||
ui_container: &mut ui::Container) {
|
||||
let elements = self.elements.as_mut().unwrap();
|
||||
|
||||
elements.logo.tick(renderer, ui_container);
|
||||
|
|
|
@ -25,18 +25,24 @@ use ui;
|
|||
#[allow(unused_variables)]
|
||||
pub trait Screen {
|
||||
// Called once
|
||||
fn init(&mut self, _renderer: &mut render::Renderer, ui_container: &mut ui::Container) {}
|
||||
fn deinit(&mut self, _renderer: &mut render::Renderer, ui_container: &mut ui::Container) {}
|
||||
fn init(&mut self, _renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
}
|
||||
fn deinit(&mut self, _renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
}
|
||||
|
||||
// May be called multiple times
|
||||
fn on_active(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container);
|
||||
fn on_deactive(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container);
|
||||
|
||||
// Called every frame the screen is active
|
||||
fn tick(&mut self, delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container);
|
||||
fn tick(&mut self,
|
||||
delta: f64,
|
||||
renderer: &mut render::Renderer,
|
||||
ui_container: &mut ui::Container);
|
||||
|
||||
// Events
|
||||
fn on_scroll(&mut self, x: f64, y: f64) {}
|
||||
fn on_scroll(&mut self, x: f64, y: f64) {
|
||||
}
|
||||
}
|
||||
|
||||
struct ScreenInfo {
|
||||
|
@ -77,7 +83,10 @@ impl ScreenSystem {
|
|||
self.add_screen(screen);
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
pub fn tick(&mut self,
|
||||
delta: f64,
|
||||
renderer: &mut render::Renderer,
|
||||
ui_container: &mut ui::Container) {
|
||||
for screen in &mut self.remove_queue {
|
||||
if screen.active {
|
||||
screen.screen.on_deactive(renderer, ui_container);
|
||||
|
@ -124,41 +133,145 @@ impl ScreenSystem {
|
|||
pub fn new_button(renderer: &mut render::Renderer, x: f64, y: f64, w: f64, h: f64) -> ui::Batch {
|
||||
let mut batch = ui::Batch::new(x, y, w, h);
|
||||
|
||||
let texture = render::Renderer::get_texture(renderer.get_textures_ref(), "gui/widgets").relative(
|
||||
0.0, 66.0 / 256.0, 200.0 / 256.0, 20.0 / 256.0
|
||||
);
|
||||
let texture = render::Renderer::get_texture(renderer.get_textures_ref(), "gui/widgets")
|
||||
.relative(0.0, 66.0 / 256.0, 200.0 / 256.0, 20.0 / 256.0);
|
||||
|
||||
// Corners
|
||||
batch.add(ui::Image::new(texture.clone(), 0.0, 0.0, 4.0, 4.0, 0.0, 0.0, 2.0 / 200.0, 2.0 / 20.0, 255, 255, 255));
|
||||
batch.add(ui::Image::new(texture.clone(), w - 4.0, 0.0, 4.0, 4.0, 198.0 / 200.0, 0.0, 2.0 / 200.0, 2.0 / 20.0, 255, 255, 255));
|
||||
batch.add(ui::Image::new(texture.clone(), 0.0, h - 6.0, 4.0, 6.0, 0.0, 17.0 / 20.0, 2.0 / 200.0, 3.0 / 20.0, 255, 255, 255));
|
||||
batch.add(ui::Image::new(texture.clone(), w - 4.0, h - 6.0, 4.0, 6.0, 198.0 / 200.0, 17.0 / 20.0, 2.0 / 200.0, 3.0 / 20.0, 255, 255, 255));
|
||||
batch.add(ui::Image::new(texture.clone(),
|
||||
0.0,
|
||||
0.0,
|
||||
4.0,
|
||||
4.0,
|
||||
0.0,
|
||||
0.0,
|
||||
2.0 / 200.0,
|
||||
2.0 / 20.0,
|
||||
255,
|
||||
255,
|
||||
255));
|
||||
batch.add(ui::Image::new(texture.clone(),
|
||||
w - 4.0,
|
||||
0.0,
|
||||
4.0,
|
||||
4.0,
|
||||
198.0 / 200.0,
|
||||
0.0,
|
||||
2.0 / 200.0,
|
||||
2.0 / 20.0,
|
||||
255,
|
||||
255,
|
||||
255));
|
||||
batch.add(ui::Image::new(texture.clone(),
|
||||
0.0,
|
||||
h - 6.0,
|
||||
4.0,
|
||||
6.0,
|
||||
0.0,
|
||||
17.0 / 20.0,
|
||||
2.0 / 200.0,
|
||||
3.0 / 20.0,
|
||||
255,
|
||||
255,
|
||||
255));
|
||||
batch.add(ui::Image::new(texture.clone(),
|
||||
w - 4.0,
|
||||
h - 6.0,
|
||||
4.0,
|
||||
6.0,
|
||||
198.0 / 200.0,
|
||||
17.0 / 20.0,
|
||||
2.0 / 200.0,
|
||||
3.0 / 20.0,
|
||||
255,
|
||||
255,
|
||||
255));
|
||||
|
||||
// Widths
|
||||
batch.add(ui::Image::new(texture.clone().relative(
|
||||
2.0 / 200.0, 0.0, 196.0 / 200.0, 2.0 / 20.0
|
||||
), 4.0, 0.0, w - 8.0, 4.0, 0.0, 0.0, 1.0, 1.0, 255, 255, 255));
|
||||
batch.add(ui::Image::new(texture.clone().relative(
|
||||
2.0 / 200.0, 17.0 / 20.0, 196.0 / 200.0, 3.0 / 20.0
|
||||
), 4.0, h - 6.0, w - 8.0, 6.0, 0.0, 0.0, 1.0, 1.0, 255, 255, 255));
|
||||
batch.add(ui::Image::new(texture.clone()
|
||||
.relative(2.0 / 200.0, 0.0, 196.0 / 200.0, 2.0 / 20.0),
|
||||
4.0,
|
||||
0.0,
|
||||
w - 8.0,
|
||||
4.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
255,
|
||||
255,
|
||||
255));
|
||||
batch.add(ui::Image::new(texture.clone().relative(2.0 / 200.0,
|
||||
17.0 / 20.0,
|
||||
196.0 / 200.0,
|
||||
3.0 / 20.0),
|
||||
4.0,
|
||||
h - 6.0,
|
||||
w - 8.0,
|
||||
6.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
255,
|
||||
255,
|
||||
255));
|
||||
|
||||
// Heights
|
||||
batch.add(ui::Image::new(texture.clone().relative(
|
||||
0.0, 2.0 / 20.0, 2.0 / 200.0, 15.0 / 20.0
|
||||
), 0.0, 4.0, 4.0, h - 10.0, 0.0, 0.0, 1.0, 1.0, 255, 255, 255));
|
||||
batch.add(ui::Image::new(texture.clone().relative(
|
||||
198.0 / 200.0, 2.0 / 20.0, 2.0 / 200.0, 15.0 / 20.0
|
||||
), w - 4.0, 4.0, 4.0, h - 10.0, 0.0, 0.0, 1.0, 1.0, 255, 255, 255));
|
||||
batch.add(ui::Image::new(texture.clone().relative(0.0, 2.0 / 20.0, 2.0 / 200.0, 15.0 / 20.0),
|
||||
0.0,
|
||||
4.0,
|
||||
4.0,
|
||||
h - 10.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
255,
|
||||
255,
|
||||
255));
|
||||
batch.add(ui::Image::new(texture.clone().relative(198.0 / 200.0,
|
||||
2.0 / 20.0,
|
||||
2.0 / 200.0,
|
||||
15.0 / 20.0),
|
||||
w - 4.0,
|
||||
4.0,
|
||||
4.0,
|
||||
h - 10.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
255,
|
||||
255,
|
||||
255));
|
||||
|
||||
// Center
|
||||
batch.add(ui::Image::new(texture.clone().relative(
|
||||
2.0 / 200.0, 2.0 / 20.0, 196.0 / 200.0, 15.0 / 20.0
|
||||
), 4.0, 4.0, w - 8.0, h - 10.0, 0.0, 0.0, 1.0, 1.0, 255, 255, 255));
|
||||
batch.add(ui::Image::new(texture.clone().relative(2.0 / 200.0,
|
||||
2.0 / 20.0,
|
||||
196.0 / 200.0,
|
||||
15.0 / 20.0),
|
||||
4.0,
|
||||
4.0,
|
||||
w - 8.0,
|
||||
h - 10.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
255,
|
||||
255,
|
||||
255));
|
||||
|
||||
batch
|
||||
}
|
||||
|
||||
pub fn new_button_text(renderer: &mut render::Renderer, val: &str, x: f64, y: f64, w: f64, h: f64) -> (ui::Batch, ui::Text) {
|
||||
pub fn new_button_text(renderer: &mut render::Renderer,
|
||||
val: &str,
|
||||
x: f64,
|
||||
y: f64,
|
||||
w: f64,
|
||||
h: f64)
|
||||
-> (ui::Batch, ui::Text) {
|
||||
let batch = new_button(renderer, x, y, w, h);
|
||||
let mut text = ui::Text::new(renderer, val, 0.0, 0.0, 255, 255, 255);
|
||||
text.set_v_attach(ui::VAttach::Middle);
|
||||
|
@ -167,14 +280,21 @@ pub fn new_button_text(renderer: &mut render::Renderer, val: &str, x: f64, y: f6
|
|||
}
|
||||
|
||||
pub fn button_action(ui_container: &mut ui::Container,
|
||||
btn: ui::ElementRef<ui::Batch>, txt: Option<ui::ElementRef<ui::Text>>,
|
||||
click: Option<ui::ClickFunc>
|
||||
) {
|
||||
btn: ui::ElementRef<ui::Batch>,
|
||||
txt: Option<ui::ElementRef<ui::Text>>,
|
||||
click: Option<ui::ClickFunc>) {
|
||||
let batch = ui_container.get_mut(&btn);
|
||||
batch.add_hover_func(Rc::new(move |over, game, ui_container| {
|
||||
let texture = render::Renderer::get_texture(game.renderer.get_textures_ref(), "gui/widgets").relative(
|
||||
0.0, (if over { 86.0 } else { 66.0 }) / 256.0, 200.0 / 256.0, 20.0 / 256.0
|
||||
);
|
||||
let texture = render::Renderer::get_texture(game.renderer.get_textures_ref(),
|
||||
"gui/widgets")
|
||||
.relative(0.0,
|
||||
(if over {
|
||||
86.0
|
||||
} else {
|
||||
66.0
|
||||
}) / 256.0,
|
||||
200.0 / 256.0,
|
||||
20.0 / 256.0);
|
||||
|
||||
{
|
||||
let batch = ui_container.get_mut(&btn);
|
||||
|
@ -182,21 +302,26 @@ pub fn button_action(ui_container: &mut ui::Container,
|
|||
let img = batch.get_mut_at::<ui::Image>(i);
|
||||
match i {
|
||||
_i @ 0 ...3 => img.set_texture(texture.clone()),
|
||||
4 => img.set_texture(texture.clone().relative(
|
||||
2.0 / 200.0, 0.0, 196.0 / 200.0, 2.0 / 20.0
|
||||
)),
|
||||
5 => img.set_texture(texture.clone().relative(
|
||||
2.0 / 200.0, 17.0 / 20.0, 196.0 / 200.0, 3.0 / 20.0
|
||||
)),
|
||||
6 => img.set_texture(texture.clone().relative(
|
||||
0.0, 2.0 / 20.0, 2.0 / 200.0, 15.0 / 20.0
|
||||
)),
|
||||
7 => img.set_texture(texture.clone().relative(
|
||||
198.0 / 200.0, 2.0 / 20.0, 2.0 / 200.0, 15.0 / 20.0
|
||||
)),
|
||||
8 => img.set_texture(texture.clone().relative(
|
||||
2.0 / 200.0, 2.0 / 20.0, 196.0 / 200.0, 15.0 / 20.0
|
||||
)),
|
||||
4 => img.set_texture(texture.clone().relative(2.0 / 200.0,
|
||||
0.0,
|
||||
196.0 / 200.0,
|
||||
2.0 / 20.0)),
|
||||
5 => img.set_texture(texture.clone().relative(2.0 / 200.0,
|
||||
17.0 / 20.0,
|
||||
196.0 / 200.0,
|
||||
3.0 / 20.0)),
|
||||
6 => img.set_texture(texture.clone().relative(0.0,
|
||||
2.0 / 20.0,
|
||||
2.0 / 200.0,
|
||||
15.0 / 20.0)),
|
||||
7 => img.set_texture(texture.clone().relative(198.0 / 200.0,
|
||||
2.0 / 20.0,
|
||||
2.0 / 200.0,
|
||||
15.0 / 20.0)),
|
||||
8 => img.set_texture(texture.clone().relative(2.0 / 200.0,
|
||||
2.0 / 20.0,
|
||||
196.0 / 200.0,
|
||||
15.0 / 20.0)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -204,7 +329,11 @@ pub fn button_action(ui_container: &mut ui::Container,
|
|||
let txt = txt.clone();
|
||||
if let Some(txt) = txt {
|
||||
let text = ui_container.get_mut(&txt);
|
||||
text.set_b(if over { 160 } else { 255 });
|
||||
text.set_b(if over {
|
||||
160
|
||||
} else {
|
||||
255
|
||||
});
|
||||
}
|
||||
}));
|
||||
if let Some(click) = click {
|
||||
|
|
|
@ -29,7 +29,7 @@ use time;
|
|||
use image;
|
||||
use rustc_serialize::base64::FromBase64;
|
||||
use rand;
|
||||
use rand::{Rng};
|
||||
use rand::Rng;
|
||||
|
||||
pub struct ServerList {
|
||||
elements: Option<UIElements>,
|
||||
|
@ -92,7 +92,9 @@ impl ServerList {
|
|||
}
|
||||
}
|
||||
|
||||
fn reload_server_list(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
fn reload_server_list(&mut self,
|
||||
renderer: &mut render::Renderer,
|
||||
ui_container: &mut ui::Container) {
|
||||
let elements = self.elements.as_mut().unwrap();
|
||||
*self.needs_reload.borrow_mut() = false;
|
||||
{
|
||||
|
@ -116,7 +118,8 @@ impl ServerList {
|
|||
let mut offset = 0.0;
|
||||
|
||||
// Default icon whilst we ping the servers or if the server doesn't provide one
|
||||
let default_icon = render::Renderer::get_texture(renderer.get_textures_ref(), "misc/unknown_server");
|
||||
let default_icon = render::Renderer::get_texture(renderer.get_textures_ref(),
|
||||
"misc/unknown_server");
|
||||
// General gui icons
|
||||
let icons = render::Renderer::get_texture(renderer.get_textures_ref(), "gui/icons");
|
||||
|
||||
|
@ -127,7 +130,18 @@ impl ServerList {
|
|||
let solid = render::Renderer::get_texture(renderer.get_textures_ref(), "steven:solid");
|
||||
|
||||
// Everything is attached to this
|
||||
let mut back = ui::Image::new(solid, 0.0, offset * 100.0, 700.0, 100.0, 0.0, 0.0, 1.0, 1.0, 0, 0, 0);
|
||||
let mut back = ui::Image::new(solid,
|
||||
0.0,
|
||||
offset * 100.0,
|
||||
700.0,
|
||||
100.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
back.set_a(100);
|
||||
back.set_v_attach(ui::VAttach::Middle);
|
||||
back.set_h_attach(ui::HAttach::Center);
|
||||
|
@ -158,7 +172,11 @@ impl ServerList {
|
|||
let address = address.clone();
|
||||
back.add_hover_func(Rc::new(move |over, _, ui_container| {
|
||||
let back = ui_container.get_mut(&back_ref);
|
||||
back.set_a(if over { 200 } else { 100 });
|
||||
back.set_a(if over {
|
||||
200
|
||||
} else {
|
||||
100
|
||||
});
|
||||
}));
|
||||
|
||||
back.add_click_func(Rc::new(move |_, _| {
|
||||
|
@ -172,12 +190,34 @@ impl ServerList {
|
|||
server.collection.add(ui_container.add(text));
|
||||
|
||||
// Server icon
|
||||
let mut icon = ui::Image::new(default_icon.clone(), 5.0, 5.0, 90.0, 90.0, 0.0, 0.0, 1.0, 1.0, 255, 255, 255);
|
||||
let mut icon = ui::Image::new(default_icon.clone(),
|
||||
5.0,
|
||||
5.0,
|
||||
90.0,
|
||||
90.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
255,
|
||||
255,
|
||||
255);
|
||||
icon.set_parent(&server.back);
|
||||
server.icon = server.collection.add(ui_container.add(icon));
|
||||
|
||||
// Ping indicator
|
||||
let mut ping = ui::Image::new(icons.clone(), 5.0, 5.0, 20.0, 16.0, 0.0, 56.0/256.0, 10.0/256.0, 8.0/256.0, 255, 255, 255);
|
||||
let mut ping = ui::Image::new(icons.clone(),
|
||||
5.0,
|
||||
5.0,
|
||||
20.0,
|
||||
16.0,
|
||||
0.0,
|
||||
56.0 / 256.0,
|
||||
10.0 / 256.0,
|
||||
8.0 / 256.0,
|
||||
255,
|
||||
255,
|
||||
255);
|
||||
ping.set_h_attach(ui::HAttach::Right);
|
||||
ping.set_parent(&server.back);
|
||||
server.ping = server.collection.add(ui_container.add(ping));
|
||||
|
@ -189,12 +229,23 @@ impl ServerList {
|
|||
server.players = server.collection.add(ui_container.add(players));
|
||||
|
||||
// Server's message of the day
|
||||
let mut motd = ui::Formatted::with_width_limit(renderer, Component::Text(TextComponent::new("Connecting...")), 100.0, 23.0, 700.0 - (90.0 + 10.0 + 5.0));
|
||||
let mut motd =
|
||||
ui::Formatted::with_width_limit(renderer,
|
||||
Component::Text(TextComponent::new("Connecting.\
|
||||
..")),
|
||||
100.0,
|
||||
23.0,
|
||||
700.0 - (90.0 + 10.0 + 5.0));
|
||||
motd.set_parent(&server.back);
|
||||
server.motd = server.collection.add(ui_container.add(motd));
|
||||
|
||||
// Version information
|
||||
let mut version = ui::Formatted::with_width_limit(renderer, Component::Text(TextComponent::new("")), 100.0, 5.0, 700.0 - (90.0 + 10.0 + 5.0));
|
||||
let mut version =
|
||||
ui::Formatted::with_width_limit(renderer,
|
||||
Component::Text(TextComponent::new("")),
|
||||
100.0,
|
||||
5.0,
|
||||
700.0 - (90.0 + 10.0 + 5.0));
|
||||
version.set_v_attach(ui::VAttach::Bottom);
|
||||
version.set_parent(&server.back);
|
||||
server.version = server.collection.add(ui_container.add(version));
|
||||
|
@ -233,10 +284,10 @@ impl ServerList {
|
|||
let mut desc = res.0.description;
|
||||
format::convert_legacy(&mut desc);
|
||||
let favicon = if let Some(icon) = res.0.favicon {
|
||||
let data = icon["data:image/png;base64,".len()..].from_base64().unwrap();
|
||||
Some(image::load_from_memory(
|
||||
&data
|
||||
).unwrap())
|
||||
let data = icon["data:image/png;base64,".len()..]
|
||||
.from_base64()
|
||||
.unwrap();
|
||||
Some(image::load_from_memory(&data).unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -250,7 +301,7 @@ impl ServerList {
|
|||
protocol_name: res.0.version.name,
|
||||
favicon: favicon,
|
||||
}));
|
||||
},
|
||||
}
|
||||
Err(err) => {
|
||||
let e = format!("{}", err);
|
||||
let mut msg = TextComponent::new(&e);
|
||||
|
@ -265,7 +316,7 @@ impl ServerList {
|
|||
protocol_name: "".to_owned(),
|
||||
favicon: None,
|
||||
}));
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -278,21 +329,34 @@ impl super::Screen for ServerList {
|
|||
let mut elements = ui::Collection::new();
|
||||
|
||||
// Refresh the server list
|
||||
let (mut refresh, mut txt) = super::new_button_text(renderer, "Refresh", 300.0, -50.0-15.0, 100.0, 30.0);
|
||||
let (mut refresh, mut txt) = super::new_button_text(renderer,
|
||||
"Refresh",
|
||||
300.0,
|
||||
-50.0 - 15.0,
|
||||
100.0,
|
||||
30.0);
|
||||
refresh.set_v_attach(ui::VAttach::Middle);
|
||||
refresh.set_h_attach(ui::HAttach::Center);
|
||||
let re = ui_container.add(refresh);
|
||||
txt.set_parent(&re);
|
||||
let tre = ui_container.add(txt);
|
||||
let nr = self.needs_reload.clone();
|
||||
super::button_action(ui_container, re.clone(), Some(tre.clone()), Some(Rc::new(move |_, _| {
|
||||
super::button_action(ui_container,
|
||||
re.clone(),
|
||||
Some(tre.clone()),
|
||||
Some(Rc::new(move |_, _| {
|
||||
*nr.borrow_mut() = true;
|
||||
})));
|
||||
elements.add(re);
|
||||
elements.add(tre);
|
||||
|
||||
// Add a new server to the list
|
||||
let (mut add, mut txt) = super::new_button_text(renderer, "Add", 200.0, -50.0-15.0, 100.0, 30.0);
|
||||
let (mut add, mut txt) = super::new_button_text(renderer,
|
||||
"Add",
|
||||
200.0,
|
||||
-50.0 - 15.0,
|
||||
100.0,
|
||||
30.0);
|
||||
add.set_v_attach(ui::VAttach::Middle);
|
||||
add.set_h_attach(ui::HAttach::Center);
|
||||
let re = ui_container.add(add);
|
||||
|
@ -307,7 +371,19 @@ impl super::Screen for ServerList {
|
|||
options.set_v_attach(ui::VAttach::Bottom);
|
||||
options.set_h_attach(ui::HAttach::Right);
|
||||
let re = ui_container.add(options);
|
||||
let mut cog = ui::Image::new(render::Renderer::get_texture(renderer.get_textures_ref(), "steven:gui/cog"), 0.0, 0.0, 40.0, 40.0, 0.0, 0.0, 1.0, 1.0, 255, 255, 255);
|
||||
let mut cog = ui::Image::new(render::Renderer::get_texture(renderer.get_textures_ref(),
|
||||
"steven:gui/cog"),
|
||||
0.0,
|
||||
0.0,
|
||||
40.0,
|
||||
40.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
255,
|
||||
255,
|
||||
255);
|
||||
cog.set_parent(&re);
|
||||
cog.set_v_attach(ui::VAttach::Middle);
|
||||
cog.set_h_attach(ui::HAttach::Center);
|
||||
|
@ -316,7 +392,13 @@ impl super::Screen for ServerList {
|
|||
elements.add(ui_container.add(cog));
|
||||
|
||||
// Disclaimer
|
||||
let mut warn = ui::Text::new(renderer, "Not affiliated with Mojang/Minecraft", 5.0, 5.0, 255, 200, 200);
|
||||
let mut warn = ui::Text::new(renderer,
|
||||
"Not affiliated with Mojang/Minecraft",
|
||||
5.0,
|
||||
5.0,
|
||||
255,
|
||||
200,
|
||||
200);
|
||||
warn.set_v_attach(ui::VAttach::Bottom);
|
||||
warn.set_h_attach(ui::HAttach::Right);
|
||||
elements.add(ui_container.add(warn));
|
||||
|
@ -325,15 +407,26 @@ impl super::Screen for ServerList {
|
|||
if let Some(ref disconnect_reason) = self.disconnect_reason {
|
||||
let mut dis_msg = ui::Text::new(renderer, "Disconnected", 0.0, 32.0, 255, 0, 0);
|
||||
dis_msg.set_h_attach(ui::HAttach::Center);
|
||||
let mut dis = ui::Formatted::with_width_limit(renderer, disconnect_reason.clone(), 0.0, 48.0, 600.0);
|
||||
let mut dis = ui::Formatted::with_width_limit(renderer,
|
||||
disconnect_reason.clone(),
|
||||
0.0,
|
||||
48.0,
|
||||
600.0);
|
||||
dis.set_h_attach(ui::HAttach::Center);
|
||||
let mut back = ui::Image::new(
|
||||
render::Renderer::get_texture(renderer.get_textures_ref(), "steven:solid"),
|
||||
0.0, 30.0,
|
||||
dis.get_width().max(dis_msg.get_width()) + 4.0, dis.get_height() + 4.0 + 16.0,
|
||||
0.0, 0.0, 1.0, 1.0,
|
||||
0, 0, 0
|
||||
);
|
||||
let mut back =
|
||||
ui::Image::new(render::Renderer::get_texture(renderer.get_textures_ref(),
|
||||
"steven:solid"),
|
||||
0.0,
|
||||
30.0,
|
||||
dis.get_width().max(dis_msg.get_width()) + 4.0,
|
||||
dis.get_height() + 4.0 + 16.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
back.set_a(100);
|
||||
back.set_h_attach(ui::HAttach::Center);
|
||||
elements.add(ui_container.add(back));
|
||||
|
@ -362,7 +455,10 @@ impl super::Screen for ServerList {
|
|||
self.elements = None
|
||||
}
|
||||
|
||||
fn tick(&mut self, delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
fn tick(&mut self,
|
||||
delta: f64,
|
||||
renderer: &mut render::Renderer,
|
||||
ui_container: &mut ui::Container) {
|
||||
if *self.needs_reload.borrow() {
|
||||
self.reload_server_list(renderer, ui_container);
|
||||
}
|
||||
|
@ -430,21 +526,26 @@ impl super::Screen for ServerList {
|
|||
}
|
||||
}
|
||||
if let Some(favicon) = res.favicon {
|
||||
let name: String = rand::thread_rng().gen_ascii_chars().take(30).collect();
|
||||
let name: String = rand::thread_rng()
|
||||
.gen_ascii_chars()
|
||||
.take(30)
|
||||
.collect();
|
||||
let tex = renderer.get_textures_ref();
|
||||
s.icon_texture = Some(name.clone());
|
||||
let icon_tex = tex.write().unwrap().put_dynamic("steven_icon", &name, favicon);
|
||||
let icon_tex = tex.write()
|
||||
.unwrap()
|
||||
.put_dynamic("steven_icon", &name, favicon);
|
||||
let icon = ui_container.get_mut(&s.icon);
|
||||
icon.set_texture(icon_tex);
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(mpsc::TryRecvError::Disconnected) => {
|
||||
s.done_ping = true;
|
||||
let motd = ui_container.get_mut(&s.motd);
|
||||
let mut txt = TextComponent::new("Channel dropped");
|
||||
txt.modifier.color = Some(format::Color::Red);
|
||||
motd.set_component(renderer, Component::Text(txt));
|
||||
},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
pub struct Map {
|
||||
bits: Vec<u64>,
|
||||
bit_size: usize,
|
||||
length: usize
|
||||
length: usize,
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -52,7 +52,7 @@ impl Map {
|
|||
let mut map = Map {
|
||||
bit_size: size,
|
||||
length: len,
|
||||
bits: Vec::with_capacity((len*size)/64)
|
||||
bits: Vec::with_capacity((len * size) / 64),
|
||||
};
|
||||
for _ in 0..len {
|
||||
map.bits.push(0)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
pub struct Set {
|
||||
data : Vec<u64>
|
||||
data: Vec<u64>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -33,9 +33,7 @@ fn test_set() {
|
|||
|
||||
impl Set {
|
||||
pub fn new(size: usize) -> Set {
|
||||
let mut set = Set {
|
||||
data: Vec::with_capacity(size)
|
||||
};
|
||||
let mut set = Set { data: Vec::with_capacity(size) };
|
||||
for _ in 0..size {
|
||||
set.data.push(0)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
extern crate byteorder;
|
||||
|
||||
use std::fmt;
|
||||
use protocol::{Serializable};
|
||||
use protocol::Serializable;
|
||||
use std::io;
|
||||
use std::io::{Read, Write};
|
||||
use self::byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
|
||||
|
@ -26,11 +26,8 @@ pub struct Position(u64);
|
|||
impl Position {
|
||||
#[allow(dead_code)]
|
||||
fn new(x: i32, y: i32, z: i32) -> Position {
|
||||
Position(
|
||||
(((x as u64) & 0x3FFFFFF) << 38) |
|
||||
(((y as u64) & 0xFFF) << 26) |
|
||||
((z as u64) & 0x3FFFFFF)
|
||||
)
|
||||
Position((((x as u64) & 0x3FFFFFF) << 38) | (((y as u64) & 0xFFF) << 26) |
|
||||
((z as u64) & 0x3FFFFFF))
|
||||
}
|
||||
|
||||
fn get_x(&self) -> i32 {
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::io;
|
|||
use std::io::{Read, Write};
|
||||
use std::fmt;
|
||||
use protocol;
|
||||
use protocol::{Serializable};
|
||||
use protocol::Serializable;
|
||||
use format;
|
||||
use item;
|
||||
|
||||
|
@ -78,11 +78,10 @@ impl Serializable for Metadata {
|
|||
4 => m.put_raw(index, try!(format::Component::read_from(buf))),
|
||||
5 => m.put_raw(index, try!(Option::<item::Stack>::read_from(buf))),
|
||||
6 => m.put_raw(index, try!(bool::read_from(buf))),
|
||||
7 => m.put_raw(index, [
|
||||
7 => m.put_raw(index,
|
||||
[try!(f32::read_from(buf)),
|
||||
try!(f32::read_from(buf)),
|
||||
try!(f32::read_from(buf)),
|
||||
try!(f32::read_from(buf))
|
||||
]),
|
||||
try!(f32::read_from(buf))]),
|
||||
8 => m.put_raw(index, try!(super::Position::read_from(buf))),
|
||||
9 => {
|
||||
if try!(bool::read_from(buf)) {
|
||||
|
@ -90,7 +89,7 @@ impl Serializable for Metadata {
|
|||
} else {
|
||||
m.put_raw::<Option<super::Position>>(index, None);
|
||||
}
|
||||
},
|
||||
}
|
||||
10 => m.put_raw(index, try!(protocol::VarInt::read_from(buf))),
|
||||
11 => {
|
||||
if try!(bool::read_from(buf)) {
|
||||
|
@ -98,9 +97,11 @@ impl Serializable for Metadata {
|
|||
} else {
|
||||
m.put_raw::<Option<protocol::UUID>>(index, None);
|
||||
}
|
||||
},
|
||||
}
|
||||
12 => m.put_raw(index, try!(protocol::VarInt::read_from(buf)).0 as u16),
|
||||
_ => return Err(io::Error::new(io::ErrorKind::InvalidInput, protocol::Error::Err("unknown metadata type".to_owned()))),
|
||||
_ => return Err(io::Error::new(io::ErrorKind::InvalidInput,
|
||||
protocol::Error::Err("unknown metadata type"
|
||||
.to_owned()))),
|
||||
}
|
||||
}
|
||||
Ok(m)
|
||||
|
@ -113,46 +114,46 @@ impl Serializable for Metadata {
|
|||
Value::Byte(ref val) => {
|
||||
try!(u8::write_to(&0, buf));
|
||||
try!(val.write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::Int(ref val) => {
|
||||
try!(u8::write_to(&1, buf));
|
||||
try!(protocol::VarInt(*val).write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::Float(ref val) => {
|
||||
try!(u8::write_to(&2, buf));
|
||||
try!(val.write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::String(ref val) => {
|
||||
try!(u8::write_to(&3, buf));
|
||||
try!(val.write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::FormatComponent(ref val) => {
|
||||
try!(u8::write_to(&4, buf));
|
||||
try!(val.write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::OptionalItemStack(ref val) => {
|
||||
try!(u8::write_to(&5, buf));
|
||||
try!(val.write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::Bool(ref val) => {
|
||||
try!(u8::write_to(&6, buf));
|
||||
try!(val.write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::Vector(ref val) => {
|
||||
try!(u8::write_to(&7, buf));
|
||||
try!(val[0].write_to(buf));
|
||||
try!(val[1].write_to(buf));
|
||||
try!(val[2].write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::Position(ref val) => {
|
||||
try!(u8::write_to(&8, buf));
|
||||
try!(val.write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::OptionalPosition(ref val) => {
|
||||
try!(u8::write_to(&9, buf));
|
||||
try!(val.is_some().write_to(buf));
|
||||
try!(val.write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::Direction(ref val) => {
|
||||
try!(u8::write_to(&10, buf));
|
||||
try!(val.write_to(buf));
|
||||
|
@ -161,7 +162,7 @@ impl Serializable for Metadata {
|
|||
try!(u8::write_to(&11, buf));
|
||||
try!(val.is_some().write_to(buf));
|
||||
try!(val.write_to(buf));
|
||||
},
|
||||
}
|
||||
Value::Block(ref val) => {
|
||||
try!(u8::write_to(&11, buf));
|
||||
try!(protocol::VarInt(*val as i32).write_to(buf));
|
||||
|
|
|
@ -35,13 +35,20 @@ impl Batch {
|
|||
width: w,
|
||||
height: h,
|
||||
|
||||
elements: Vec::new()
|
||||
elements: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
fn update(&mut self, _: &mut render::Renderer) {}
|
||||
fn update(&mut self, _: &mut render::Renderer) {
|
||||
}
|
||||
|
||||
fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, delta: f64) -> &Vec<u8> {
|
||||
fn draw(&mut self,
|
||||
renderer: &mut render::Renderer,
|
||||
r: &Region,
|
||||
width: f64,
|
||||
height: f64,
|
||||
delta: f64)
|
||||
-> &Vec<u8> {
|
||||
if self.dirty {
|
||||
self.dirty = false;
|
||||
self.data.clear();
|
||||
|
@ -64,7 +71,10 @@ impl Batch {
|
|||
|
||||
pub fn add<T: UIElement>(&mut self, e: T) -> BatchRef<T> {
|
||||
self.elements.push(e.wrap());
|
||||
BatchRef { index: self.elements.len() - 1, ty: PhantomData }
|
||||
BatchRef {
|
||||
index: self.elements.len() - 1,
|
||||
ty: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<T: UIElement>(&self, r: BatchRef<T>) -> &T {
|
||||
|
|
|
@ -27,7 +27,11 @@ ui_element!(Formatted {
|
|||
impl Formatted {
|
||||
base_impl!();
|
||||
|
||||
pub fn new(renderer: &mut render::Renderer, val: format::Component, x: f64, y: f64) -> Formatted {
|
||||
pub fn new(renderer: &mut render::Renderer,
|
||||
val: format::Component,
|
||||
x: f64,
|
||||
y: f64)
|
||||
-> Formatted {
|
||||
let mut f = ui_create!(Formatted {
|
||||
val: val,
|
||||
x: x,
|
||||
|
@ -39,13 +43,18 @@ impl Formatted {
|
|||
|
||||
text: Vec::new(),
|
||||
max_width: -1.0,
|
||||
lines: 0
|
||||
lines: 0,
|
||||
});
|
||||
f.init_component(renderer);
|
||||
f
|
||||
}
|
||||
|
||||
pub fn with_width_limit(renderer: &mut render::Renderer, val: format::Component, x: f64, y: f64, max_width: f64) -> Formatted {
|
||||
pub fn with_width_limit(renderer: &mut render::Renderer,
|
||||
val: format::Component,
|
||||
x: f64,
|
||||
y: f64,
|
||||
max_width: f64)
|
||||
-> Formatted {
|
||||
let mut f = ui_create!(Formatted {
|
||||
val: val,
|
||||
x: x,
|
||||
|
@ -57,7 +66,7 @@ impl Formatted {
|
|||
|
||||
text: Vec::new(),
|
||||
max_width: max_width,
|
||||
lines: 0
|
||||
lines: 0,
|
||||
});
|
||||
f.init_component(renderer);
|
||||
f
|
||||
|
@ -90,7 +99,13 @@ impl Formatted {
|
|||
self.init_component(renderer);
|
||||
}
|
||||
|
||||
fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, delta: f64) -> &Vec<u8> {
|
||||
fn draw(&mut self,
|
||||
renderer: &mut render::Renderer,
|
||||
r: &Region,
|
||||
width: f64,
|
||||
height: f64,
|
||||
delta: f64)
|
||||
-> &Vec<u8> {
|
||||
if self.dirty {
|
||||
self.dirty = false;
|
||||
self.data.clear();
|
||||
|
@ -107,7 +122,8 @@ impl Formatted {
|
|||
}
|
||||
|
||||
pub fn get_size(&self) -> (f64, f64) {
|
||||
((self.width + 2.0) * self.scale_x, self.height * self.scale_y)
|
||||
((self.width + 2.0) * self.scale_x,
|
||||
self.height * self.scale_y)
|
||||
}
|
||||
|
||||
lazy_field!(width, f64, get_width, set_width);
|
||||
|
@ -146,8 +162,6 @@ struct FormatState<'a> {
|
|||
renderer: &'a render::Renderer,
|
||||
}
|
||||
|
||||
type GetColorFn = Fn() -> format::Color;
|
||||
|
||||
impl <'a> FormatState<'a> {
|
||||
fn build(&mut self, c: &format::Component, color: format::Color) {
|
||||
match c {
|
||||
|
@ -160,7 +174,7 @@ impl <'a> FormatState<'a> {
|
|||
self.build(e, col);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,7 +185,13 @@ impl <'a> FormatState<'a> {
|
|||
let size = self.renderer.ui.size_of_char(c) + 2.0;
|
||||
if (self.max_width > 0.0 && self.offset + width + size > self.max_width) || c == '\n' {
|
||||
let (rr, gg, bb) = color.to_rgb();
|
||||
let text = Text::new(self.renderer, &txt[last .. i], self.offset, (self.lines*18 + 1) as f64, rr, gg, bb);
|
||||
let text = Text::new(self.renderer,
|
||||
&txt[last..i],
|
||||
self.offset,
|
||||
(self.lines * 18 + 1) as f64,
|
||||
rr,
|
||||
gg,
|
||||
bb);
|
||||
self.text.push(text.wrap());
|
||||
last = i;
|
||||
if c == '\n' {
|
||||
|
@ -189,7 +209,13 @@ impl <'a> FormatState<'a> {
|
|||
|
||||
if last != txt.len() {
|
||||
let (rr, gg, bb) = color.to_rgb();
|
||||
let text = Text::new(self.renderer, &txt[last..], self.offset, (self.lines*18 + 1) as f64, rr, gg, bb);
|
||||
let text = Text::new(self.renderer,
|
||||
&txt[last..],
|
||||
self.offset,
|
||||
(self.lines * 18 + 1) as f64,
|
||||
rr,
|
||||
gg,
|
||||
bb);
|
||||
self.offset += text.width + 4.0; // TODO Why is this 4 not 2?
|
||||
self.text.push(text.wrap());
|
||||
if self.offset > self.width {
|
||||
|
|
|
@ -31,7 +31,19 @@ ui_element!(Image {
|
|||
impl Image {
|
||||
base_impl!();
|
||||
|
||||
pub fn new(texture: render::Texture, x: f64, y: f64, w: f64, h: f64, t_x: f64, t_y: f64, t_width: f64, t_height: f64, r: u8, g: u8, b: u8) -> Image {
|
||||
pub fn new(texture: render::Texture,
|
||||
x: f64,
|
||||
y: f64,
|
||||
w: f64,
|
||||
h: f64,
|
||||
t_x: f64,
|
||||
t_y: f64,
|
||||
t_width: f64,
|
||||
t_height: f64,
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8)
|
||||
-> Image {
|
||||
ui_create!(Image {
|
||||
texture: texture,
|
||||
x: x,
|
||||
|
@ -47,17 +59,32 @@ impl Image {
|
|||
r: r,
|
||||
g: g,
|
||||
b: b,
|
||||
a: 255
|
||||
a: 255,
|
||||
})
|
||||
}
|
||||
|
||||
fn update(&mut self, _: &mut render::Renderer) {}
|
||||
fn update(&mut self, _: &mut render::Renderer) {
|
||||
}
|
||||
|
||||
fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, _: f64) -> &Vec<u8> {
|
||||
fn draw(&mut self,
|
||||
renderer: &mut render::Renderer,
|
||||
r: &Region,
|
||||
width: f64,
|
||||
height: f64,
|
||||
_: f64)
|
||||
-> &Vec<u8> {
|
||||
if self.dirty {
|
||||
self.dirty = false;
|
||||
self.texture = renderer.check_texture(self.texture.clone());
|
||||
let mut e = render::ui::UIElement::new(&self.texture, r.x, r.y, r.w, r.h, self.t_x, self.t_y, self.t_width, self.t_height);
|
||||
let mut e = render::ui::UIElement::new(&self.texture,
|
||||
r.x,
|
||||
r.y,
|
||||
r.w,
|
||||
r.h,
|
||||
self.t_x,
|
||||
self.t_y,
|
||||
self.t_width,
|
||||
self.t_height);
|
||||
e.r = self.r;
|
||||
e.g = self.g;
|
||||
e.b = self.b;
|
||||
|
|
|
@ -22,7 +22,10 @@ pub struct Logo {
|
|||
}
|
||||
|
||||
impl Logo {
|
||||
pub fn new(resources: Arc<RwLock<resources::Manager>>, renderer: &mut render::Renderer, ui_container: &mut ui::Container) -> Logo {
|
||||
pub fn new(resources: Arc<RwLock<resources::Manager>>,
|
||||
renderer: &mut render::Renderer,
|
||||
ui_container: &mut ui::Container)
|
||||
-> Logo {
|
||||
let mut l = Logo {
|
||||
resources: resources,
|
||||
shadow: Default::default(),
|
||||
|
@ -69,22 +72,34 @@ impl Logo {
|
|||
} else {
|
||||
(170, 170, 170)
|
||||
};
|
||||
let mut shadow = ui::Image::new(
|
||||
solid.clone(),
|
||||
(x+2) as f64, (y+4) as f64, 4.0, 8.0,
|
||||
0.0, 0.0, 1.0, 1.0,
|
||||
0, 0, 0
|
||||
);
|
||||
let mut shadow = ui::Image::new(solid.clone(),
|
||||
(x + 2) as f64,
|
||||
(y + 4) as f64,
|
||||
4.0,
|
||||
8.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
1.0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
shadow.set_a(100);
|
||||
shadow_batch.add(shadow);
|
||||
|
||||
|
||||
let img = ui::Image::new(
|
||||
stone.clone(),
|
||||
x as f64, y as f64, 4.0, 8.0,
|
||||
(x%16) as f64 / 16.0, (y%16) as f64 / 16.0, 4.0/16.0, 8.0/16.0,
|
||||
r, g, b
|
||||
);
|
||||
let img = ui::Image::new(stone.clone(),
|
||||
x as f64,
|
||||
y as f64,
|
||||
4.0,
|
||||
8.0,
|
||||
(x % 16) as f64 / 16.0,
|
||||
(y % 16) as f64 / 16.0,
|
||||
4.0 / 16.0,
|
||||
8.0 / 16.0,
|
||||
r,
|
||||
g,
|
||||
b);
|
||||
layer0.add(img);
|
||||
|
||||
let width = (x + 4) as f64;
|
||||
|
|
|
@ -162,7 +162,7 @@ element_impl!(
|
|||
|
||||
pub enum Mode {
|
||||
Scaled,
|
||||
Unscaled(f64)
|
||||
Unscaled(f64),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
|
@ -189,9 +189,7 @@ struct Region {
|
|||
|
||||
impl Region {
|
||||
fn intersects(&self, o: &Region) -> bool {
|
||||
!(self.x+self.w < o.x ||
|
||||
self.x > o.x+o.w ||
|
||||
self.y+self.h < o.y ||
|
||||
!(self.x + self.w < o.x || self.x > o.x + o.w || self.y + self.h < o.y ||
|
||||
self.y > o.y + o.h)
|
||||
}
|
||||
}
|
||||
|
@ -234,9 +232,7 @@ pub struct Collection {
|
|||
|
||||
impl Collection {
|
||||
pub fn new() -> Collection {
|
||||
Collection {
|
||||
elements: Vec::new(),
|
||||
}
|
||||
Collection { elements: Vec::new() }
|
||||
}
|
||||
|
||||
pub fn add<T: UIElement>(&mut self, element: ElementRef<T>) -> ElementRef<T> {
|
||||
|
@ -252,7 +248,12 @@ impl Collection {
|
|||
}
|
||||
}
|
||||
|
||||
const SCREEN: Region = Region{x: 0.0, y: 0.0, w: SCALED_WIDTH, h: SCALED_HEIGHT};
|
||||
const SCREEN: Region = Region {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
w: SCALED_WIDTH,
|
||||
h: SCALED_HEIGHT,
|
||||
};
|
||||
|
||||
pub struct Container {
|
||||
pub mode: Mode,
|
||||
|
@ -288,7 +289,10 @@ impl Container {
|
|||
}
|
||||
self.elements.insert(r, e.wrap());
|
||||
self.elements_list.push(r);
|
||||
ElementRef{inner: r, ty: PhantomData}
|
||||
ElementRef {
|
||||
inner: r,
|
||||
ty: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<T: UIElement>(&self, r: &ElementRef<T>) -> &T {
|
||||
|
@ -305,7 +309,8 @@ impl Container {
|
|||
|
||||
fn remove_raw(&mut self, r: &ElementRefInner) {
|
||||
self.elements.remove(&r);
|
||||
self.elements_list.iter()
|
||||
self.elements_list
|
||||
.iter()
|
||||
.position(|&e| e.index == r.index)
|
||||
.map(|e| self.elements_list.remove(e))
|
||||
.unwrap();
|
||||
|
@ -317,9 +322,8 @@ impl Container {
|
|||
Mode::Unscaled(scale) => (scale, scale),
|
||||
};
|
||||
|
||||
if self.last_sw != sw || self.last_sh != sh
|
||||
|| self.last_width != width || self.last_height != height
|
||||
|| self.version != renderer.ui.version {
|
||||
if self.last_sw != sw || self.last_sh != sh || self.last_width != width ||
|
||||
self.last_height != height || self.version != renderer.ui.version {
|
||||
self.last_sw = sw;
|
||||
self.last_sh = sh;
|
||||
self.last_width = width;
|
||||
|
@ -411,7 +415,9 @@ impl Container {
|
|||
let funcs = e.get_hover_funcs();
|
||||
if !funcs.is_empty() {
|
||||
let r = self.get_draw_region(e, sw, sh);
|
||||
hovers.push((*re, funcs, mx >= r.x && mx <= r.x + r.w && my >= r.y && my <= r.y + r.h));
|
||||
hovers.push((*re,
|
||||
funcs,
|
||||
mx >= r.x && mx <= r.x + r.w && my >= r.y && my <= r.y + r.h));
|
||||
}
|
||||
}
|
||||
for hover in &hovers {
|
||||
|
@ -436,7 +442,12 @@ impl Container {
|
|||
}
|
||||
|
||||
fn get_draw_region_raw(e: &Element, sw: f64, sh: f64, super_region: &Region) -> Region {
|
||||
let mut r = Region{x:0.0,y:0.0,w:0.0,h:0.0};
|
||||
let mut r = Region {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
w: 0.0,
|
||||
h: 0.0,
|
||||
};
|
||||
let (w, h) = e.get_size();
|
||||
let (ox, oy) = e.get_offset();
|
||||
r.w = w * sw;
|
||||
|
@ -532,7 +543,7 @@ macro_rules! base_impl {
|
|||
|
||||
macro_rules! ui_create {
|
||||
($name:ident {
|
||||
$($field:ident: $e:expr),+
|
||||
$($field:ident: $e:expr,)+
|
||||
}) => (
|
||||
$name {
|
||||
dirty: true,
|
||||
|
|
|
@ -28,7 +28,14 @@ ui_element!(Text {
|
|||
impl Text {
|
||||
base_impl!();
|
||||
|
||||
pub fn new(renderer: &render::Renderer, val: &str, x: f64, y: f64, r: u8, g: u8, b: u8) -> Text {
|
||||
pub fn new(renderer: &render::Renderer,
|
||||
val: &str,
|
||||
x: f64,
|
||||
y: f64,
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8)
|
||||
-> Text {
|
||||
ui_create!(Text {
|
||||
val: val.to_owned(),
|
||||
x: x,
|
||||
|
@ -41,7 +48,7 @@ impl Text {
|
|||
r: r,
|
||||
g: g,
|
||||
b: b,
|
||||
a: 255
|
||||
a: 255,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -49,13 +56,26 @@ impl Text {
|
|||
self.width = renderer.ui.size_of_string(&self.val);
|
||||
}
|
||||
|
||||
fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, width: f64, height: f64, _: f64) -> &Vec<u8> {
|
||||
fn draw(&mut self,
|
||||
renderer: &mut render::Renderer,
|
||||
r: &Region,
|
||||
width: f64,
|
||||
height: f64,
|
||||
_: f64)
|
||||
-> &Vec<u8> {
|
||||
if self.dirty {
|
||||
self.dirty = false;
|
||||
let sx = r.w / self.width;
|
||||
let sy = r.h / self.height;
|
||||
let mut text = if self.rotation == 0.0 {
|
||||
renderer.ui.new_text_scaled(&self.val, r.x, r.y, sx*self.scale_x, sy*self.scale_y, self.r, self.g, self.b)
|
||||
renderer.ui.new_text_scaled(&self.val,
|
||||
r.x,
|
||||
r.y,
|
||||
sx * self.scale_x,
|
||||
sy * self.scale_y,
|
||||
self.r,
|
||||
self.g,
|
||||
self.b)
|
||||
} else {
|
||||
let c = self.rotation.cos();
|
||||
let s = self.rotation.sin();
|
||||
|
@ -63,7 +83,15 @@ impl Text {
|
|||
let tmpy = r.h / 2.0;
|
||||
let w = (tmpx * c - tmpy * s).abs();
|
||||
let h = (tmpy * c + tmpx * s).abs();
|
||||
renderer.ui.new_text_rotated(&self.val, r.x+w-(r.w / 2.0), r.y+h-(r.h / 2.0), sx*self.scale_x, sy*self.scale_y, self.rotation, self.r, self.g, self.b)
|
||||
renderer.ui.new_text_rotated(&self.val,
|
||||
r.x + w - (r.w / 2.0),
|
||||
r.y + h - (r.h / 2.0),
|
||||
sx * self.scale_x,
|
||||
sy * self.scale_y,
|
||||
self.rotation,
|
||||
self.r,
|
||||
self.g,
|
||||
self.b)
|
||||
};
|
||||
for e in &mut text.elements {
|
||||
e.a = self.a;
|
||||
|
@ -75,7 +103,8 @@ impl Text {
|
|||
}
|
||||
|
||||
pub fn get_size(&self) -> (f64, f64) {
|
||||
((self.width + 2.0) * self.scale_x, self.height * self.scale_y)
|
||||
((self.width + 2.0) * self.scale_x,
|
||||
self.height * self.scale_y)
|
||||
}
|
||||
|
||||
pub fn get_text(&self) -> &str {
|
||||
|
|
Loading…
Reference in New Issue