Compare commits

..

No commits in common. "aa4c6c18b3ea5458328c3040b4e73e0e933a291f" and "1f154c1a5817f8ccd15a1c65ceb63158bbf546e2" have entirely different histories.

21 changed files with 136 additions and 191 deletions

1
.gitignore vendored
View File

@ -1,3 +1,2 @@
/cache
/target /target
*.ignore *.ignore

16
TODO.md
View File

@ -1,9 +1,10 @@
## Specific Jobs ## Specific Jobs
- Particle variation - Particle variation
- Animated sprites
- UI: health, shield, fuel, heat, energy bars - UI: health, shield, fuel, heat, energy bars
- UI: text arranger - UI: text arranger
- Sound system - Sound system
- Ship death animation & debris - Debris on ship death
---------------------------------- ----------------------------------
@ -56,11 +57,6 @@
- how to target them - how to target them
- where to go - where to go
- etc, extra flags - etc, extra flags
- Conditional animations: on fire, on death, etc (tempest)
- Higher texture limit (16 x 8096 x 8096 isn't enough)
- Fast-load menu, progress bar for the rest
- Only load what is needed?
- GPU limits? (texture size, texture number)
## Faction interaction ## Faction interaction
@ -77,6 +73,7 @@
- Frame timings (compute/render/physics/etc) - Frame timings (compute/render/physics/etc)
- Elegantly handle lost focus - Elegantly handle lost focus
- Pause game - Pause game
- Better player controller? (only one shipbehavior needs inputs)
- Clear all `// TODO:` comments littered in the source - Clear all `// TODO:` comments littered in the source
- CLI options (debug, save location, content location, check content) - CLI options (debug, save location, content location, check content)
- Config file and compile options, remove all those consts. - Config file and compile options, remove all those consts.
@ -84,10 +81,6 @@
- Sprite optimization: do we need to allocate a new `Vec` every frame? Probably not. - Sprite optimization: do we need to allocate a new `Vec` every frame? Probably not.
- Better error when run outside of directory - Better error when run outside of directory
- Documentation site & front page - Documentation site & front page
- Random animation age for objects * ui
- Random animation delay/fps?
- Fade between animation frames
- Better WGSL preprocessor (warning when including a bad file!)
## Content ## Content
- Angled engines - Angled engines
@ -95,6 +88,7 @@
- Turn engine flares - Turn engine flares
- Reverse engine & flares - Reverse engine & flares
- Better ship colliders (need a tool or an algorithm) - Better ship colliders (need a tool or an algorithm)
- Better projectile colliders (box/ball/etc -- shared syntax)
- Turrets - Turrets
- Weapons with ammunition - Weapons with ammunition
- Enable/disable weapons - Enable/disable weapons
@ -117,6 +111,7 @@
- Important objects affect camera - Important objects affect camera
## Visuals ## Visuals
- Particles
- Dynamic lighting (planets & ships) - Dynamic lighting (planets & ships)
- Motion blur - Motion blur
- Zoom parallax (?) - Zoom parallax (?)
@ -125,7 +120,6 @@
- Ship outlines in radar - Ship outlines in radar
- Engine flare ease in/out - Engine flare ease in/out
- Lens flare - Lens flare
- Particles when a ship is damaged
## Write and Document ## Write and Document
- Parallax - Parallax

View File

@ -1,5 +1,5 @@
[ship."Gypsum"] [ship."Gypsum"]
sprite = "ship::gypsum" sprite = "ship::peregrine"
size = 100 size = 100
mass = 1 mass = 1
hull = 200 hull = 200

View File

@ -20,8 +20,8 @@ file = "projectile/blaster.png"
file = "ship/gypsum.png" file = "ship/gypsum.png"
[sprite."ship::peregrine"] [sprite."ship::peregrine"]
duration = 1.3 duration = 1
repeat = "reverse" repeat = "repeat"
frames = [ frames = [
"ship/peregrine/01.png", "ship/peregrine/01.png",
"ship/peregrine/02.png", "ship/peregrine/02.png",

View File

@ -1,7 +1,6 @@
#![warn(missing_docs)] #![warn(missing_docs)]
//! Compile-time parameters //! Compile-time parameters
// TODO: many of these should be moved to a config file or cli option
/// Minimum zoom level /// Minimum zoom level
pub const ZOOM_MIN: f32 = 200.0; pub const ZOOM_MIN: f32 = 200.0;
@ -62,6 +61,3 @@ pub const SPRITE_LIMIT: u32 = 1024;
/// The maximum number of images we can load /// The maximum number of images we can load
pub const IMAGE_LIMIT: u32 = 1024; pub const IMAGE_LIMIT: u32 = 1024;
/// Where we should look for packed assets
pub const ASSET_CACHE: &'static str = "./cache";

View File

@ -255,11 +255,6 @@ impl Content {
return &self.sprites[h.index as usize]; return &self.sprites[h.index as usize];
} }
/// Get the list of atlas files we may use
pub fn atlas_files(&self) -> &Vec<String> {
return &self.sprite_atlas.atlas_list;
}
/// Get a sprite from a path /// Get a sprite from a path
pub fn get_image(&self, p: &Path) -> &SpriteAtlasImage { pub fn get_image(&self, p: &Path) -> &SpriteAtlasImage {
self.sprite_atlas.index.get(p).unwrap() self.sprite_atlas.index.get(p).unwrap()

View File

@ -44,10 +44,6 @@ pub enum RepeatMode {
/// After the first frame, jump to the last frame /// After the first frame, jump to the last frame
#[serde(rename = "repeat")] #[serde(rename = "repeat")]
Repeat, Repeat,
/// Play this animation in reverse after the last frame
#[serde(rename = "reverse")]
Reverse,
} }
impl RepeatMode { impl RepeatMode {
@ -55,9 +51,8 @@ impl RepeatMode {
/// Used to pass this enum into shaders /// Used to pass this enum into shaders
pub fn as_int(&self) -> u32 { pub fn as_int(&self) -> u32 {
match self { match self {
Self::Repeat => 0, Self::Once => 0,
Self::Once => 1, Self::Repeat => 1,
Self::Reverse => 2,
} }
} }
} }

View File

@ -4,12 +4,9 @@ mod inputstatus;
pub use galactica_content as content; pub use galactica_content as content;
use anyhow::{bail, Result}; use anyhow::Result;
use galactica_constants::{self, ASSET_CACHE}; use galactica_constants;
use std::{ use std::path::PathBuf;
fs,
path::{Path, PathBuf},
};
use winit::{ use winit::{
event::{Event, KeyboardInput, WindowEvent}, event::{Event, KeyboardInput, WindowEvent},
event_loop::{ControlFlow, EventLoop}, event_loop::{ControlFlow, EventLoop},
@ -17,20 +14,11 @@ use winit::{
}; };
fn main() -> Result<()> { fn main() -> Result<()> {
let cache_dir = Path::new(ASSET_CACHE); // TODO: error if missing
fs::create_dir_all(cache_dir)?;
let atlas_index = cache_dir.join("spriteatlas.toml");
if !atlas_index.exists() {
bail!("Could not find sprite atlas!");
}
// TODO: pretty error if missing
let content = content::Content::load_dir( let content = content::Content::load_dir(
PathBuf::from(galactica_constants::CONTENT_ROOT), PathBuf::from(galactica_constants::CONTENT_ROOT),
PathBuf::from(galactica_constants::IMAGE_ROOT), PathBuf::from(galactica_constants::IMAGE_ROOT),
atlas_index, PathBuf::from("spriteatlas.toml"),
galactica_constants::STARFIELD_SPRITE_NAME.to_owned(), galactica_constants::STARFIELD_SPRITE_NAME.to_owned(),
)?; )?;

View File

@ -78,10 +78,8 @@ impl AtlasSet {
pub fn write_image(&mut self, path: &Path, dim: [u32; 2]) -> Result<usize> { pub fn write_image(&mut self, path: &Path, dim: [u32; 2]) -> Result<usize> {
let mut f = File::open(&path)?; let mut f = File::open(&path)?;
let mut bytes = Vec::new(); let mut bytes = Vec::new();
f.read_to_end(&mut bytes) f.read_to_end(&mut bytes)?;
.with_context(|| format!("While reading file `{}`", path.display()))?; let img = image::load_from_memory(&bytes)?;
let img = image::load_from_memory(&bytes)
.with_context(|| format!("While loading file `{}`", path.display()))?;
let mut x = 0; let mut x = 0;
let mut y = 0; let mut y = 0;
@ -181,7 +179,7 @@ impl AtlasSet {
self.index.index.insert( self.index.index.insert(
p.to_path_buf(), p.to_path_buf(),
SpriteAtlasImage { SpriteAtlasImage {
atlas: atlas_idx as u32, atlas: atlas_idx,
x: x as f32 / self.texture_width as f32, x: x as f32 / self.texture_width as f32,
y: y as f32 / self.texture_height as f32, y: y as f32 / self.texture_height as f32,
w: dim[0] as f32 / self.texture_width as f32, w: dim[0] as f32 / self.texture_width as f32,
@ -192,17 +190,13 @@ impl AtlasSet {
return Ok(atlas_idx); return Ok(atlas_idx);
} }
pub fn save_files<F>(mut self, atlas_path: F, index_path: &Path) -> Result<()> pub fn save_files<F>(self, atlas_path: F, index_path: &Path) -> Result<()>
where where
F: Fn(usize) -> PathBuf, F: Fn(usize) -> PathBuf,
{ {
// Save atlases // Save atlases
for i in 0..self.texture_list.len() { for i in 0..self.texture_list.len() {
let path = atlas_path(i); self.texture_list[i].save(atlas_path(i))?;
self.texture_list[i].save(&path)?;
self.index
.atlas_list
.push(path.file_name().unwrap().to_str().unwrap().to_owned());
} }
// Save index // Save index

View File

@ -11,8 +11,7 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SpriteAtlasImage { pub struct SpriteAtlasImage {
/// The index of the atlas this image is in /// The index of the atlas this image is in
/// This is an index in SpriteAtlas.atlas_list pub atlas: usize,
pub atlas: u32,
/// x-position of this image /// x-position of this image
/// (between 0 and 1, using wgpu texture coordinates) /// (between 0 and 1, using wgpu texture coordinates)
@ -37,9 +36,6 @@ pub struct SpriteAtlasImage {
pub struct SpriteAtlas { pub struct SpriteAtlas {
/// The images in this atlas /// The images in this atlas
pub index: HashMap<PathBuf, SpriteAtlasImage>, pub index: HashMap<PathBuf, SpriteAtlasImage>,
/// The file names of the atlas textures we've generated
pub atlas_list: Vec<String>,
} }
impl SpriteAtlas { impl SpriteAtlas {
@ -47,7 +43,6 @@ impl SpriteAtlas {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
index: HashMap::new(), index: HashMap::new(),
atlas_list: Vec::new(),
} }
} }
} }

View File

@ -2,16 +2,16 @@ mod atlasset;
use atlasset::AtlasSet; use atlasset::AtlasSet;
use anyhow::{bail, Context, Result}; use anyhow::{bail, Result};
use image::io::Reader; use image::io::Reader;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use walkdir::WalkDir; use walkdir::WalkDir;
// TODO: warning when images have extra transparency // TODO: warning when images have extra transparency
// TODO: don't re-encode. Direct to gpu?
// (maybe not, tiling is slow. Make it work with files first.)
// TODO: path for atlas files
// TODO: dynamic packing (for plugins) // TODO: dynamic packing (for plugins)
// TODO: standalone cli (galactica should ask to run this)
// TODO: randomly assign sprites to textures, for efficiency
// TODO: group images by use case
fn main() -> Result<()> { fn main() -> Result<()> {
let mut files = Vec::new(); let mut files = Vec::new();
@ -38,11 +38,8 @@ fn main() -> Result<()> {
} }
let path = e.path().to_path_buf(); let path = e.path().to_path_buf();
let reader = Reader::open(&path) let reader = Reader::open(&path)?;
.with_context(|| format!("While reading file `{}`", path.display()))?; let dim = reader.into_dimensions()?;
let dim = reader.into_dimensions().with_context(|| {
format!("While reading dimensions of file `{}`", path.display())
})?;
files.push((path, [dim.0, dim.1])); files.push((path, [dim.0, dim.1]));
total_dim += dim.0 as f64 * dim.1 as f64; total_dim += dim.0 as f64 * dim.1 as f64;
} }

View File

@ -1,43 +0,0 @@
// Pick frame of animation from an instance.
//
// This function assumes that the uniform header has been loaded,
// and that `InstanceInput` contains a field `texture_index`
fn animate(instance: InstanceInput, age: f32) -> u32 {
let idx = instance.texture_index;
let len = sprites.data[idx].frame_count;
let rep = sprites.data[idx].repeatmode;
let fps = sprites.data[idx].fps;
var frame: u32 = u32(0);
// Repeat
if rep == u32(1) {
frame = u32(min(
(age / fps),
f32(len) - 1.0
));
// Reverse
} else if rep == u32(2) {
let x = age / fps;
let m = f32(len) * 2.0 - 1.0;
// x fmod m
frame = u32(x - floor(x / m) * m);
if frame >= len {
frame = len + len - frame - u32(1);
}
// Repeat (default)
} else {
let x = age / fps;
let m = f32(len);
// x fmod m
frame = u32(x - floor(x / m) * m);
}
return frame + sprites.data[idx].first_frame;
}

View File

@ -26,7 +26,39 @@ var texture_array: binding_array<texture_2d<f32>>;
var sampler_array: binding_array<sampler>; var sampler_array: binding_array<sampler>;
// INCLUDE: animate.wgsl fn fmod(x: f32, m: f32) -> f32 {
return x - floor(x / m) * m;
}
// Returns texture index
// TODO: random age
// TODO: preprocessor include function
// TODO: packed location config, better error
// TODO: bounce animations
// TODO: animation randomness?
fn animate(instance: InstanceInput) -> u32 {
// Age doesn't make sense here, so arbitrarily pick zero.
let age = global.current_time.x;
let len = sprites.data[instance.texture_index].frame_count;
let rep = sprites.data[instance.texture_index].repeatmode;
let fps = sprites.data[instance.texture_index].fps;
var frame: u32 = u32(0);
if rep == u32(1) {
// Repeat
frame = u32(fmod(
(age / fps),
f32(len)
));
} else {
// Once
frame = u32(min(
(age / fps),
f32(len) - 1.0
));
}
return frame + sprites.data[instance.texture_index].first_frame;
}
@vertex @vertex
fn vertex_main( fn vertex_main(
@ -44,8 +76,8 @@ fn vertex_main(
var out: VertexOutput; var out: VertexOutput;
out.position = transform * vec4<f32>(vertex.position, 1.0); out.position = transform * vec4<f32>(vertex.position, 1.0);
let t = atlas.data[animate(instance, global.current_time.x)]; let t = atlas.data[animate(instance)];
out.texture_index = t.atlas_texture; out.texture_index = u32(0);
out.texture_coords = vec2(t.xpos, t.ypos); out.texture_coords = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 { if vertex.texture_coords.x == 1.0 {
out.texture_coords = vec2(out.texture_coords.x + t.width, out.texture_coords.y); out.texture_coords = vec2(out.texture_coords.x + t.width, out.texture_coords.y);

View File

@ -29,7 +29,33 @@ var texture_array: binding_array<texture_2d<f32>>;
var sampler_array: binding_array<sampler>; var sampler_array: binding_array<sampler>;
// INCLUDE: animate.wgsl // Returns texture index
fn animate(instance: InstanceInput) -> u32 {
let age = global.current_time.x - instance.created;
let len = sprites.data[instance.texture_index].frame_count;
let rep = sprites.data[instance.texture_index].repeatmode;
let fps = sprites.data[instance.texture_index].fps;
var frame: u32 = u32(0);
if rep == u32(1) {
// Repeat
frame = u32(fmod(
(age / fps),
f32(len)
));
} else {
// Once
frame = u32(min(
(age / fps),
f32(len) - 1.0
));
}
return frame + sprites.data[instance.texture_index].first_frame;
}
fn fmod(x: f32, m: f32) -> f32 {
return x - floor(x / m) * m;
}
@vertex @vertex
fn vertex_main( fn vertex_main(
@ -40,25 +66,51 @@ fn vertex_main(
var out: VertexOutput; var out: VertexOutput;
out.texture_coords = vertex.texture_coords; out.texture_coords = vertex.texture_coords;
// Skip expired particles
if instance.expires < global.current_time.x { if instance.expires < global.current_time.x {
out.texture_index = u32(0); out.texture_index = u32(0);
// Draw off screen
out.position = vec4<f32>(2.0, 2.0, 0.0, 1.0); out.position = vec4<f32>(2.0, 2.0, 0.0, 1.0);
return out; return out;
} }
let age = global.current_time.x - instance.created; let age = global.current_time.x - instance.created;
// Apply transformations let len = sprites.data[instance.texture_index].frame_count;
let rep = sprites.data[instance.texture_index].repeatmode;
let fps = sprites.data[instance.texture_index].fps;
var frame: u32 = u32(0);
if rep == u32(1) {
// Repeat
frame = u32(fmod(
(age / fps),
f32(len)
));
} else {
// Once
frame = u32(min(
(age / fps),
f32(len) - 1.0
));
}
let t = atlas.data[animate(instance)];
out.texture_index = u32(0);
out.texture_coords = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 {
out.texture_coords = vec2(out.texture_coords.x + t.width, out.texture_coords.y);
}
if vertex.texture_coords.y == 1.0 {
out.texture_coords = vec2(out.texture_coords.x, out.texture_coords.y + t.height);
}
let rotation = mat2x2(instance.rotation_0, instance.rotation_1); let rotation = mat2x2(instance.rotation_0, instance.rotation_1);
var scale: f32 = instance.size / global.camera_zoom.x; var scale: f32 = instance.size / global.camera_zoom.x;
var pos: vec2<f32> = vec2(vertex.position.x, vertex.position.y); var pos: vec2<f32> = vec2(vertex.position.x, vertex.position.y);
pos = pos * vec2<f32>( pos = pos * vec2<f32>(
sprites.data[instance.texture_index].aspect * scale / global.window_aspect.x, sprites.data[instance.texture_index].aspect * scale / global.window_aspect.x,
scale scale
); );
pos = rotation * pos; pos = rotation * pos;
var ipos: vec2<f32> = ( var ipos: vec2<f32> = (
@ -73,19 +125,6 @@ fn vertex_main(
); );
out.position = vec4<f32>(pos, 0.0, 1.0); out.position = vec4<f32>(pos, 0.0, 1.0);
// Compute texture coordinates
let t = atlas.data[animate(instance, age)];
out.texture_index = u32(t.atlas_texture);
out.texture_coords = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 {
out.texture_coords = vec2(out.texture_coords.x + t.width, out.texture_coords.y);
}
if vertex.texture_coords.y == 1.0 {
out.texture_coords = vec2(out.texture_coords.x, out.texture_coords.y + t.height);
}
return out; return out;
} }

View File

@ -25,6 +25,7 @@ var sampler_array: binding_array<sampler>;
fn fmod(x: vec2<f32>, m: f32) -> vec2<f32> { fn fmod(x: vec2<f32>, m: f32) -> vec2<f32> {
return x - floor(x / m) * m; return x - floor(x / m) * m;
} }
@ -107,11 +108,9 @@ fn vertex_main(
out.position = vec4<f32>(pos, 0.0, 1.0) * instance.position.z; out.position = vec4<f32>(pos, 0.0, 1.0) * instance.position.z;
// Starfield sprites may not be animated
let i = sprites.data[global.starfield_sprite.x].first_frame; let i = sprites.data[global.starfield_sprite.x].first_frame;
let t = atlas.data[i]; let t = atlas.data[i];
out.texture_index = u32(t.atlas_texture); out.texture_index = u32(0);
out.texture_coords = vec2(t.xpos, t.ypos); out.texture_coords = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 { if vertex.texture_coords.x == 1.0 {
out.texture_coords = vec2(out.texture_coords.x + t.width, out.texture_coords.y); out.texture_coords = vec2(out.texture_coords.x + t.width, out.texture_coords.y);

View File

@ -27,7 +27,6 @@ var texture_array: binding_array<texture_2d<f32>>;
var sampler_array: binding_array<sampler>; var sampler_array: binding_array<sampler>;
// INCLUDE: animate.wgsl
@vertex @vertex
@ -47,9 +46,9 @@ fn vertex_main(
out.position = transform * vec4<f32>(vertex.position, 1.0); out.position = transform * vec4<f32>(vertex.position, 1.0);
out.color_transform = instance.color_transform; out.color_transform = instance.color_transform;
// Pick texture frame let i = sprites.data[instance.texture_index].first_frame;
let t = atlas.data[animate(instance, global.current_time.x)]; let t = atlas.data[i];
out.texture_index = u32(t.atlas_texture); out.texture_index = u32(0);
out.texture_coords = vec2(t.xpos, t.ypos); out.texture_coords = vec2(t.xpos, t.ypos);
if vertex.texture_coords.x == 1.0 { if vertex.texture_coords.x == 1.0 {
out.texture_coords = vec2(out.texture_coords.x + t.width, out.texture_coords.y); out.texture_coords = vec2(out.texture_coords.x + t.width, out.texture_coords.y);

View File

@ -11,11 +11,6 @@ pub struct ImageLocation {
pub ypos: f32, pub ypos: f32,
pub width: f32, pub width: f32,
pub height: f32, pub height: f32,
// The index of the texture this image is in
pub atlas_texture: u32,
pub _padding: [f32; 3],
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]

View File

@ -44,12 +44,6 @@ impl GlobalUniform {
ypos: f32, ypos: f32,
width: f32, width: f32,
height: f32, height: f32,
atlas_texture: u32,
padding_a: f32,
padding_b: f32,
padding_c: f32,
}; };
"#, "#,
); );

View File

@ -60,29 +60,17 @@ struct VertexBuffers {
particle: Rc<VertexBuffer>, particle: Rc<VertexBuffer>,
} }
/// Basic wgsl preprocesser /// Preprocess shader files
fn preprocess_shader( fn preprocess_shader(
shader: &str, shader: &str,
global_uniform: &GlobalUniform, global_uniform: &GlobalUniform,
global_uniform_group: u32, global_uniform_group: u32,
) -> String { ) -> String {
// Insert dynamically-generated global definitions // Insert common headers
let shader = shader.replace( shader.replace(
"// INCLUDE: global uniform header", "// INCLUDE: global uniform header",
&global_uniform.shader_header(global_uniform_group), &global_uniform.shader_header(global_uniform_group),
); )
// Insert common functions
let shader = shader.replace(
"// INCLUDE: animate.wgsl",
&include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/shaders/include/",
"animate.wgsl"
)),
);
return shader;
} }
impl GPUState { impl GPUState {

View File

@ -4,10 +4,9 @@ use crate::{
}; };
use anyhow::Result; use anyhow::Result;
use bytemuck::Zeroable; use bytemuck::Zeroable;
use galactica_constants::ASSET_CACHE;
use galactica_packer::SpriteAtlasImage; use galactica_packer::SpriteAtlasImage;
use image::GenericImageView; use image::GenericImageView;
use std::{fs::File, io::Read, num::NonZeroU32, path::Path}; use std::{fs::File, io::Read, num::NonZeroU32};
use wgpu::BindGroupLayout; use wgpu::BindGroupLayout;
pub(crate) struct RawTexture { pub(crate) struct RawTexture {
@ -95,19 +94,11 @@ impl TextureArray {
// Load all textures // Load all textures
let mut texture_data = Vec::new(); let mut texture_data = Vec::new();
for a in ct.atlas_files() { println!("opening image");
println!("opening {a}"); let mut f = File::open("atlas-0.bmp")?;
let p = Path::new(ASSET_CACHE);
let mut f = File::open(p.join(a))?;
let mut bytes = Vec::new(); let mut bytes = Vec::new();
f.read_to_end(&mut bytes)?; f.read_to_end(&mut bytes)?;
texture_data.push(RawTexture::from_bytes( texture_data.push(RawTexture::from_bytes(&device, &queue, &bytes, "Atlas")?);
&device,
&queue,
&bytes,
&format!("Atlas `{a}`"),
)?);
}
let mut image_locations = ImageLocationArray::zeroed(); let mut image_locations = ImageLocationArray::zeroed();
let mut sprite_data = SpriteDataArray::zeroed(); let mut sprite_data = SpriteDataArray::zeroed();
@ -134,8 +125,6 @@ impl TextureArray {
ypos: image.y, ypos: image.y,
width: image.w, width: image.w,
height: image.h, height: image.h,
atlas_texture: image.atlas,
_padding: Default::default(),
}; };
image_counter += 1; image_counter += 1;
} }

View File

@ -20,7 +20,7 @@ pub fn build_radar(
let hide_range = 0.85; let hide_range = 0.85;
let shrink_distance = 20.0; let shrink_distance = 20.0;
let system_object_scale = 1.0 / 600.0; let system_object_scale = 1.0 / 600.0;
let ship_scale = 1.0 / 15.0; let ship_scale = 1.0 / 10.0;
let (_, player_body) = physics.get_ship_body(player).unwrap(); let (_, player_body) = physics.get_ship_body(player).unwrap();
let player_position = util::rigidbody_position(player_body); let player_position = util::rigidbody_position(player_body);