Compare commits

..

No commits in common. "5279eeb7d45bf5c8857a365f09f1a93f67918722" and "b6df512b9090d3161777e86080fcb989a5f45ed4" have entirely different histories.

15 changed files with 42 additions and 274 deletions

20
Cargo.lock generated
View File

@ -543,7 +543,6 @@ dependencies = [
"rand",
"serde",
"toml",
"walkdir",
"wgpu",
"winit",
]
@ -1383,15 +1382,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
@ -1685,16 +1675,6 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "walkdir"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"

View File

@ -40,4 +40,3 @@ pollster = "0.3"
anyhow = "1.0"
cgmath = "0.18.0"
rand = "0.8.5"
walkdir = "2.4.0"

View File

@ -1,13 +0,0 @@
# content type: system
[system]
name = "12 Autumn above"
[object.star]
sprite = "star::a0"
center = [0.0, 0.0]
[object.earth]
sprite = "planet::earth"
center = "star"
radius = 200
angle = 14

View File

@ -1,32 +0,0 @@
use anyhow::Result;
use super::{syntax, ContentType};
#[derive(Debug)]
pub struct Content {
systems: Vec<syntax::System>,
}
impl Content {
pub fn new(cv: Vec<ContentType>) -> Result<Self> {
let mut content = Self {
systems: Vec::new(),
};
// TODO: locate bad files
// These methods check intra-file consistency
for c in cv {
match c {
ContentType::System(v) => content.add_system(v)?,
};
}
return Ok(content);
}
fn add_system(&mut self, toml: syntax::system::toml::SystemRoot) -> Result<()> {
self.systems.push(syntax::System::parse(toml)?);
return Ok(());
}
}

View File

@ -1,30 +0,0 @@
use anyhow::Result;
use std::{fs::File, io::Read, path::Path};
use super::syntax;
#[derive(Debug)]
pub enum ContentType {
System(syntax::system::toml::SystemRoot),
}
// TODO: check content without loading game
impl ContentType {
pub fn try_parse(file_string: &str) -> Result<Option<Self>> {
// TODO: More advanced parsing, read the whole top comment
let (first, _) = file_string.split_once("\n").unwrap();
let type_spec = first[1..].trim(); // Remove hash
return Ok(match type_spec {
"content type: system" => Some(Self::System(toml::from_str(&file_string)?)),
_ => None,
});
}
pub fn from_path(path: &Path) -> Result<Option<Self>> {
let mut file_string = String::new();
let _ = File::open(path)?.read_to_string(&mut file_string);
let file_string = file_string.trim();
return Self::try_parse(&file_string);
}
}

View File

@ -1,6 +0,0 @@
mod content;
mod contenttype;
mod syntax;
pub use content::Content;
pub use contenttype::ContentType;

View File

@ -1,3 +0,0 @@
#![allow(dead_code)]
pub mod system;
pub use system::System;

View File

@ -1,95 +0,0 @@
use anyhow::{bail, Result};
use cgmath::Point2;
use std::collections::HashMap;
use crate::physics::Pfloat;
/// Toml file syntax
pub(in crate::content) mod toml {
use super::Pfloat;
use serde::Deserialize;
use std::collections::HashMap;
#[derive(Debug, Deserialize)]
pub struct SystemRoot {
pub system: System,
pub object: HashMap<String, Object>,
}
#[derive(Debug, Deserialize)]
pub struct System {
pub name: String,
}
#[derive(Debug, Deserialize)]
pub struct Object {
pub sprite: String,
pub center: Center,
#[serde(default)]
pub radius: Pfloat,
#[serde(default)]
pub angle: Pfloat,
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
pub enum Center {
Label(String),
Coords([Pfloat; 2]),
}
}
#[derive(Debug)]
pub struct System {
name: String,
objects: Vec<Object>,
}
#[derive(Debug)]
struct Object {
sprite: String,
center: Point2<Pfloat>,
radius: Pfloat,
angle: Pfloat,
}
fn resolve_center(
objects: &HashMap<String, toml::Object>,
obj: &toml::Object,
) -> Option<Point2<f32>> {
match &obj.center {
toml::Center::Label(s) => resolve_center(&objects, objects.get(s)?),
toml::Center::Coords(v) => Some(Point2::from(*v)),
}
}
impl System {
pub fn parse(value: toml::SystemRoot) -> Result<Self> {
let mut objects = Vec::new();
for (_, obj) in &value.object {
let center = match resolve_center(&value.object, obj) {
Some(v) => v,
None => {
bail!(
"Failed to parse content file: could not resolve center label `{:?}`",
obj.center
);
}
};
objects.push(Object {
sprite: obj.sprite.clone(),
center,
radius: obj.radius,
angle: obj.angle,
});
}
return Ok(Self {
name: value.system.name.clone(),
objects,
});
}
}

View File

@ -1,19 +1,19 @@
use cgmath::{Deg, Point2};
use crate::{physics::Pfloat, render::SpriteTexture, Sprite, Spriteable};
use crate::{physics::Pfloat, Sprite, Spriteable};
pub struct Doodad {
pub sprite: SpriteTexture,
pub sprite: String,
pub pos: Point2<Pfloat>,
pub parallax: Pfloat,
pub height: Pfloat,
}
impl Spriteable for Doodad {
fn get_sprite(&self) -> Sprite {
fn sprite(&self) -> Sprite {
return Sprite {
texture: self.sprite.clone(),
pos: self.pos,
name: self.sprite.clone(),
angle: Deg { 0: 0.0 },
scale: 1.0,
height: self.height,

View File

@ -1,15 +1,5 @@
mod content;
mod doodad;
mod inputstatus;
mod physics;
mod render;
mod ship;
mod system;
use anyhow::Result;
use cgmath::{Deg, Point2};
use std::time::Instant;
use walkdir::WalkDir;
use winit::{
event::{
ElementState, Event, KeyboardInput, MouseButton, MouseScrollDelta, TouchPhase,
@ -19,14 +9,12 @@ use winit::{
window::WindowBuilder,
};
use crate::{
doodad::Doodad,
inputstatus::InputStatus,
physics::Pfloat,
render::{GPUState, SpriteTexture},
ship::{Ship, ShipKind},
system::System,
};
mod doodad;
mod inputstatus;
mod physics;
mod render;
mod ship;
mod system;
pub const ZOOM_MIN: Pfloat = 200.0;
pub const ZOOM_MAX: Pfloat = 2000.0;
@ -46,6 +34,15 @@ pub const STARFIELD_DENSITY: f64 = 0.01;
// Must fit inside an i32
pub const STARFIELD_COUNT: u64 = (STARFIELD_SIZE as f64 * STARFIELD_DENSITY) as u64;
use crate::{
doodad::Doodad,
inputstatus::InputStatus,
physics::Pfloat,
render::GPUState,
ship::{Ship, ShipKind},
system::System,
};
#[derive(Debug, Clone, Copy)]
struct Camera {
/// Camera center
@ -57,12 +54,12 @@ struct Camera {
}
trait Spriteable {
fn get_sprite(&self) -> Sprite;
fn sprite(&self) -> Sprite;
}
struct Sprite {
/// Name of the sprite to draw
texture: SpriteTexture,
name: String,
/// This object's position, in world coordinates.
pos: Point2<Pfloat>,
@ -146,11 +143,11 @@ impl Game {
self.last_update = Instant::now();
}
fn get_sprites(&self) -> Vec<Sprite> {
fn sprites(&self) -> Vec<Sprite> {
let mut sprites: Vec<Sprite> = Vec::new();
sprites.append(&mut self.system.get_sprites());
sprites.push(self.player.get_sprite());
sprites.append(&mut self.system.sprites());
sprites.push(self.player.sprite());
// Make sure sprites are drawn in the correct order
// (note the reversed a, b in the comparator)
@ -163,6 +160,8 @@ impl Game {
}
}
use std::time::Instant;
pub async fn run() -> Result<()> {
let event_loop = EventLoop::new();
let window = WindowBuilder::new().build(&event_loop).unwrap();
@ -231,20 +230,6 @@ pub async fn run() -> Result<()> {
}
fn main() -> Result<()> {
let mut raw_content = Vec::new();
for e in WalkDir::new("content").into_iter().filter_map(|e| e.ok()) {
if e.metadata().unwrap().is_file() {
let c = crate::content::ContentType::from_path(e.path())?;
match c {
Some(c) => raw_content.push(c),
None => continue,
}
}
}
let a = crate::content::Content::new(raw_content)?;
println!("{:?}", a);
//pollster::block_on(run())?;
pollster::block_on(run())?;
return Ok(());
}

View File

@ -215,11 +215,11 @@ impl GPUState {
let clip_ne = Point2::from((-self.window_aspect, 1.0)) * game.camera.zoom;
let clip_sw = Point2::from((self.window_aspect, -1.0)) * game.camera.zoom;
for s in game.get_sprites() {
for s in game.sprites() {
// Parallax is computed here, so we can check if this sprite is visible.
let pos =
(s.pos - game.camera.pos.to_vec()) / (s.parallax + game.camera.zoom / ZOOM_MIN);
let texture = self.texture_array.get_sprite_texture(s.texture);
let texture = self.texture_array.get_texture(&s.name[..]);
// Game dimensions of this sprite post-scale.
// Don't divide by 2, we use this later.
@ -376,7 +376,7 @@ impl GPUState {
self.window_size.height as f32,
],
window_aspect: [self.window_aspect, 0.0],
starfield_texture: [self.texture_array.get_starfield_texture().index, 0],
starfield_texture: [self.texture_array.get_starfield().index, 0],
starfield_tile_size: [STARFIELD_SIZE as f32, 0.0],
}]),
);

View File

@ -6,12 +6,6 @@ mod vertexbuffer;
pub use gpustate::GPUState;
/// A handle to a sprite texture
#[derive(Debug, Clone, Copy)]
pub struct SpriteTexture {
pub name: &'static str,
}
// API correction matrix.
// cgmath uses OpenGL's matrix format, which
// needs to be converted to wgpu's matrix format.

View File

@ -2,8 +2,6 @@ use anyhow::Result;
use std::{collections::HashMap, num::NonZeroU32, path::PathBuf};
use wgpu::BindGroupLayout;
use crate::render::SpriteTexture;
use super::{loader::TextureLoader, Texture, TextureArrayConfig};
pub struct TextureArray {
@ -16,15 +14,11 @@ pub struct TextureArray {
impl TextureArray {
const INDEX_PATH: &'static str = "assets";
pub fn get_starfield_texture(&self) -> Texture {
pub fn get_starfield(&self) -> Texture {
return self.get_texture(&self.config.starfield);
}
pub fn get_sprite_texture(&self, sprite: SpriteTexture) -> Texture {
return self.get_texture(sprite.name);
}
fn get_texture(&self, name: &str) -> Texture {
pub fn get_texture(&self, name: &str) -> Texture {
match self.textures.get(name) {
Some(x) => *x,
None => self.get_texture(&self.config.error),

View File

@ -1,18 +1,16 @@
use cgmath::Point2;
use crate::{physics::Pfloat, physics::PhysBody, render::SpriteTexture, Sprite, Spriteable};
use crate::{physics::Pfloat, physics::PhysBody, Sprite, Spriteable};
pub enum ShipKind {
Gypsum,
}
impl ShipKind {
fn sprite(&self) -> SpriteTexture {
let name = match self {
fn sprite(&self) -> &'static str {
match self {
Self::Gypsum => "ship::gypsum",
};
return SpriteTexture { name };
}
}
fn height(&self) -> Pfloat {
@ -37,10 +35,10 @@ impl Ship {
}
impl Spriteable for Ship {
fn get_sprite(&self) -> Sprite {
fn sprite(&self) -> Sprite {
return Sprite {
pos: self.body.pos,
texture: self.kind.sprite(),
name: self.kind.sprite().to_owned(),
angle: self.body.angle,
scale: 1.0,
parallax: 1.0,

View File

@ -1,6 +1,5 @@
use crate::{
physics::{Pfloat, Polar},
render::SpriteTexture,
Doodad, Sprite, Spriteable, STARFIELD_COUNT, STARFIELD_PARALLAX_MAX, STARFIELD_PARALLAX_MIN,
STARFIELD_SIZE,
};
@ -49,7 +48,7 @@ impl System {
s.bodies.push(Doodad {
pos: (0.0, 0.0).into(),
sprite: SpriteTexture { name: "star::star" },
sprite: "star::star".to_owned(),
parallax: 10.0,
height: 80.0,
});
@ -61,9 +60,7 @@ impl System {
angle: Deg { 0: 31.0 },
}
.to_cartesian(),
sprite: SpriteTexture {
name: "planet::earth",
},
sprite: "planet::earth".to_owned(),
parallax: 5.0,
height: 120.0,
});
@ -71,7 +68,7 @@ impl System {
return s;
}
pub fn get_sprites(&self) -> Vec<Sprite> {
return self.bodies.iter().map(|x| x.get_sprite()).collect();
pub fn sprites(&self) -> Vec<Sprite> {
return self.bodies.iter().map(|x| x.sprite()).collect();
}
}