mirror of
https://github.com/Theaninova/WanganSunrise.git
synced 2025-12-10 10:36:14 +00:00
feat: enma parsing
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/target
|
||||
/.direnv
|
||||
4374
Cargo.lock
generated
Normal file
4374
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
3
Cargo.toml
Normal file
3
Cargo.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
[workspace]
|
||||
members = ["bevy_nucompat", "nucompat", "enmacompat", "wangan_sunrise"]
|
||||
resolver = "2"
|
||||
9
bevy_nucompat/Cargo.toml
Normal file
9
bevy_nucompat/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "bevy_nucompat"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bevy = "0.13"
|
||||
4
bevy_nucompat/src/lib.rs
Normal file
4
bevy_nucompat/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
use bevy::asset::AssetLoader;
|
||||
|
||||
#[derive(Asset)]
|
||||
struct NutAsset {}
|
||||
10
enmacompat/Cargo.toml
Normal file
10
enmacompat/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "enmacompat"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
binrw = "0.13"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
serde = { version = "1.0.198", features = ["derive"] }
|
||||
serde_json = "1.0.116"
|
||||
118
enmacompat/src/area.rs
Normal file
118
enmacompat/src/area.rs
Normal file
@@ -0,0 +1,118 @@
|
||||
use crate::{section::EnmaSection, windows_pe::WindowsPEFile};
|
||||
use binrw::{BinRead, NullString};
|
||||
use serde::Serialize;
|
||||
|
||||
pub fn find_area_array_location(file: &mut WindowsPEFile) -> Result<Option<u64>, std::io::Error> {
|
||||
for area_name_addr in file.find_memory_address_of(b"OsDojima")? {
|
||||
println!("Possible Area Name: {:#x}", area_name_addr);
|
||||
|
||||
for area_addr in file.find_references(area_name_addr)? {
|
||||
let area_addr = area_addr - 8;
|
||||
if !file.is_exactly(area_addr, &1_u64.to_le_bytes())? {
|
||||
continue;
|
||||
}
|
||||
|
||||
println!("Possible Area: {:#x}", area_addr);
|
||||
|
||||
for area_array_addr in file.find_references(area_addr)? {
|
||||
let area_array_addr = area_array_addr - 8;
|
||||
if !file
|
||||
.is_exactly(area_array_addr, &0_u64.to_le_bytes())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
println!("Possible Area Array: {:#x}", area_array_addr);
|
||||
|
||||
if (1..10).all(|i| {
|
||||
let reference = area_array_addr + i * 8;
|
||||
file.read_addr::<u64>(reference)
|
||||
.map(|addr| {
|
||||
println!("Checking Array Member {} ({:#x})", i, addr);
|
||||
file.is_exactly(addr, &(i as u64).to_le_bytes())
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}) {
|
||||
return Ok(Some(area_array_addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn read_area(file: &WindowsPEFile, address: u64) -> Result<EnmaArea, std::io::Error> {
|
||||
let area = file.read_addr::<EnmaAreaRaw>(address)?;
|
||||
Ok(EnmaArea {
|
||||
id: area.id,
|
||||
name: file.read_addr::<NullString>(area.name_addr)?.to_string(),
|
||||
stage_id: area.stage_id,
|
||||
related_area_addr: area.related_area_addr,
|
||||
unknown: area.unk2,
|
||||
sections: (0..area.section_count)
|
||||
.map(|i| file.read_addr::<EnmaSection>(area.sections_addr + i as u64 * 0x24))
|
||||
.collect::<Result<_, _>>()?,
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct EnmaArea {
|
||||
pub id: u64,
|
||||
pub name: String,
|
||||
pub stage_id: u64,
|
||||
pub related_area_addr: [u64; 4],
|
||||
pub unknown: [f32; 4],
|
||||
pub sections: Vec<EnmaSection>,
|
||||
}
|
||||
|
||||
#[derive(BinRead, Debug)]
|
||||
#[br(little)]
|
||||
pub struct EnmaAreaRaw {
|
||||
pub id: u64,
|
||||
pub name_addr: u64,
|
||||
pub stage_id: u64,
|
||||
|
||||
pub related_area_addr: [u64; 4],
|
||||
|
||||
pub unk2: [f32; 4],
|
||||
|
||||
pub sections_addr: u64,
|
||||
pub section_count: i32,
|
||||
|
||||
pub unk1: [f32; 3],
|
||||
|
||||
pub bank_left_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub bank_right_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub zebra_left_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub zebra_right_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub gaps_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub non_guard_left_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub non_guard_right_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub speed_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub lane_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub other_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub non_lane_change_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub signs_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub notices_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub watches_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub on_comers_addr: u64,
|
||||
#[br(pad_before = 8)]
|
||||
pub pillers_addr: u64,
|
||||
}
|
||||
4
enmacompat/src/lib.rs
Normal file
4
enmacompat/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub mod area;
|
||||
pub mod section;
|
||||
mod util;
|
||||
pub mod windows_pe;
|
||||
40
enmacompat/src/main.rs
Normal file
40
enmacompat/src/main.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
use clap::{command, Parser};
|
||||
use enmacompat::{
|
||||
area::{find_area_array_location, read_area, EnmaAreaRaw},
|
||||
windows_pe::WindowsPEFile,
|
||||
};
|
||||
use std::fs::File;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version, about)]
|
||||
struct Args {
|
||||
#[clap(short, long)]
|
||||
path: std::path::PathBuf,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
let file = File::open(&args.path).expect("Failed to open file");
|
||||
let mut windows_pe_file = WindowsPEFile::from(file);
|
||||
|
||||
println!("\x1b[34m\x1b[1mSearching for Area Array Location\x1b[0m");
|
||||
let location = Some(0x1417cc980); //find_area_array_location(&mut windows_pe_file).unwrap();
|
||||
if let Some(location) = location {
|
||||
println!(
|
||||
"\x1b[32m\x1b[1mArea Array Location\x1b[0m: \x1b[4m{:#x}\x1b[0m (Memory), \x1b[4m{:#x}\x1b[0m (File)",
|
||||
location,
|
||||
windows_pe_file.get_file_address(location).unwrap()
|
||||
);
|
||||
|
||||
for i in 1..2 {
|
||||
let address = windows_pe_file.read_addr::<u64>(location + i * 8).unwrap();
|
||||
let area = read_area(&windows_pe_file, address).unwrap();
|
||||
|
||||
let file = File::create(format!("{}.json", area.name)).unwrap();
|
||||
let mut writer = std::io::BufWriter::new(file);
|
||||
serde_json::to_writer_pretty(&mut writer, &area).unwrap();
|
||||
}
|
||||
} else {
|
||||
println!("\x1b[31mArea array location could not found\x1b[0m");
|
||||
}
|
||||
}
|
||||
16
enmacompat/src/section.rs
Normal file
16
enmacompat/src/section.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use binrw::BinRead;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, BinRead, Serialize)]
|
||||
pub struct EnmaSection {
|
||||
pub distance: f32,
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
pub angle1: f32,
|
||||
pub angle2: f32,
|
||||
pub left: f32,
|
||||
pub right: f32,
|
||||
pub height: f32,
|
||||
pub unk1: f32,
|
||||
pub unk2: f32,
|
||||
}
|
||||
44
enmacompat/src/util.rs
Normal file
44
enmacompat/src/util.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use std::io::{Read, Seek, SeekFrom};
|
||||
|
||||
pub fn find_in_data<T: Read + Seek>(
|
||||
data: &mut T,
|
||||
target: &[u8],
|
||||
) -> Result<Vec<usize>, std::io::Error> {
|
||||
let pos = data.stream_position()?;
|
||||
let mut result = Vec::new();
|
||||
let mut possible = vec![false; target.len()];
|
||||
let mut possible_i = 0;
|
||||
|
||||
for (i, byte) in data.bytes().enumerate() {
|
||||
let byte = byte?;
|
||||
if possible[possible_i] {
|
||||
result.push(i - target.len());
|
||||
}
|
||||
possible[possible_i] = byte == target[possible_i];
|
||||
|
||||
for j in 0..possible.len() {
|
||||
let target_index = (possible_i + j) % target.len();
|
||||
|
||||
possible[j] = possible[j] && byte == target[target_index];
|
||||
}
|
||||
|
||||
possible_i = (possible_i + 1) % target.len();
|
||||
}
|
||||
|
||||
data.seek(SeekFrom::Start(pos))?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn is_exactly<T: Read + Seek>(
|
||||
data: &mut T,
|
||||
location: usize,
|
||||
target: &[u8],
|
||||
) -> Result<bool, std::io::Error> {
|
||||
let pos = data.stream_position()?;
|
||||
data.seek(SeekFrom::Start(location as u64))?;
|
||||
let mut buf = [0; 8];
|
||||
let result = data.read_exact(&mut buf);
|
||||
data.seek(SeekFrom::Start(pos))?;
|
||||
Ok(result.is_ok() && buf == target)
|
||||
}
|
||||
164
enmacompat/src/windows_pe.rs
Normal file
164
enmacompat/src/windows_pe.rs
Normal file
@@ -0,0 +1,164 @@
|
||||
use std::{fs::File, io::Seek};
|
||||
|
||||
use binrw::{io::BufReader, BinRead, BinReaderExt, Endian};
|
||||
|
||||
use crate::util::{find_in_data, is_exactly};
|
||||
|
||||
#[derive(BinRead)]
|
||||
#[br(little, magic = b"MZ")]
|
||||
pub struct WindowsPEHeader {
|
||||
pub last_page_size: u16,
|
||||
pub pages_in_file: u16,
|
||||
pub relocations: u16,
|
||||
pub header_size: u16,
|
||||
pub min_memory: u16,
|
||||
pub max_memory: u16,
|
||||
pub initial_ss: u16,
|
||||
pub initial_sp: u16,
|
||||
pub checksum: u16,
|
||||
pub initial_ip: u16,
|
||||
pub initial_cs: u16,
|
||||
pub relocations_offset: u16,
|
||||
pub overlay_number: u16,
|
||||
pub reserved: [u16; 4],
|
||||
pub oem_id: u16,
|
||||
pub oem_info: u16,
|
||||
pub reserved2: [u16; 10],
|
||||
pub pe_offset: u32,
|
||||
#[br(pad_before = pe_offset - 0x40)]
|
||||
pub image_nt_headers: WindowsPEImageNTHeaders,
|
||||
}
|
||||
|
||||
#[derive(BinRead)]
|
||||
#[br(little, magic = b"PE\0\0")]
|
||||
pub struct WindowsPEImageNTHeaders {
|
||||
pub machine: u16,
|
||||
pub number_of_sections: u16,
|
||||
pub time_date_stamp: u32,
|
||||
pub pointer_to_symbol_table: u32,
|
||||
pub number_of_symbols: u32,
|
||||
pub size_of_optional_header: u16,
|
||||
pub characteristics: u16,
|
||||
#[br(pad_size_to = size_of_optional_header)]
|
||||
pub optional_header: WindowsPEOptionalHeader,
|
||||
#[br(count = number_of_sections)]
|
||||
pub sections: Vec<WindowsPEImageSectionHeader>,
|
||||
}
|
||||
|
||||
#[derive(BinRead)]
|
||||
#[br(little, magic = b"\x0b\x02")]
|
||||
pub struct WindowsPEOptionalHeader {
|
||||
pub major_linker_version: u8,
|
||||
pub minor_linker_version: u8,
|
||||
pub size_of_code: u32,
|
||||
pub size_of_initialized_data: u32,
|
||||
pub size_of_uninitialized_data: u32,
|
||||
pub address_of_entry_point: u32,
|
||||
pub base_of_code: u32,
|
||||
pub image_base: u64,
|
||||
}
|
||||
|
||||
#[derive(BinRead)]
|
||||
#[br(little)]
|
||||
pub struct WindowsPEImageSectionHeader {
|
||||
pub name: [u8; 8],
|
||||
pub virtual_size: u32,
|
||||
pub virtual_address: u32,
|
||||
pub size_of_raw_data: u32,
|
||||
pub pointer_to_raw_data: u32,
|
||||
pub pointer_to_relocations: u32,
|
||||
pub pointer_to_linenumbers: u32,
|
||||
pub number_of_relocations: u16,
|
||||
pub number_of_linenumbers: u16,
|
||||
pub characteristics: u32,
|
||||
}
|
||||
|
||||
pub struct WindowsPEFile {
|
||||
pub file: File,
|
||||
pub header: WindowsPEHeader,
|
||||
}
|
||||
|
||||
impl WindowsPEFile {
|
||||
pub fn get_file_address(&self, memory_address: u64) -> Option<u64> {
|
||||
let image_base = self.header.image_nt_headers.optional_header.image_base;
|
||||
let section = self
|
||||
.header
|
||||
.image_nt_headers
|
||||
.sections
|
||||
.iter()
|
||||
.find(|section| {
|
||||
let virtual_address = section.virtual_address as u64 + image_base;
|
||||
memory_address >= virtual_address
|
||||
&& memory_address < virtual_address + section.virtual_size as u64
|
||||
})?;
|
||||
let offset = memory_address - section.virtual_address as u64 - image_base as u64
|
||||
+ section.pointer_to_raw_data as u64;
|
||||
Some(offset)
|
||||
}
|
||||
|
||||
pub fn get_memory_address(&self, file_address: u64) -> Option<u64> {
|
||||
let image_base = self.header.image_nt_headers.optional_header.image_base;
|
||||
let section = self
|
||||
.header
|
||||
.image_nt_headers
|
||||
.sections
|
||||
.iter()
|
||||
.find(|section| {
|
||||
file_address >= section.pointer_to_raw_data as u64
|
||||
&& file_address
|
||||
< section.pointer_to_raw_data as u64 + section.size_of_raw_data as u64
|
||||
})?;
|
||||
let offset = file_address - section.pointer_to_raw_data as u64
|
||||
+ image_base as u64
|
||||
+ section.virtual_address as u64;
|
||||
Some(offset)
|
||||
}
|
||||
|
||||
pub fn find_memory_address_of(&self, target: &[u8]) -> Result<Vec<u64>, std::io::Error> {
|
||||
let mut reader = BufReader::new(&self.file);
|
||||
reader.seek(std::io::SeekFrom::Start(0))?;
|
||||
let file_addr = find_in_data(&mut reader, target)?;
|
||||
Ok(file_addr
|
||||
.iter()
|
||||
.map(|file_addr| self.get_memory_address(*file_addr as u64).unwrap())
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub fn find_references(&self, address: u64) -> Result<Vec<u64>, std::io::Error> {
|
||||
self.find_memory_address_of(&address.to_le_bytes())
|
||||
}
|
||||
|
||||
pub fn is_exactly(&self, address: u64, target: &[u8]) -> Result<bool, std::io::Error> {
|
||||
let mut reader = BufReader::new(&self.file);
|
||||
self.get_file_address(address)
|
||||
.map(|file_addr| is_exactly(&mut reader, file_addr as usize, target))
|
||||
.unwrap_or(Ok(false))
|
||||
}
|
||||
|
||||
pub fn read_addr<'a, T>(&self, address: u64) -> Result<T, std::io::Error>
|
||||
where
|
||||
T: BinRead,
|
||||
T::Args<'a>: Default,
|
||||
{
|
||||
let mut reader = BufReader::new(&self.file);
|
||||
if let Some(file_addr) = self.get_file_address(address) {
|
||||
reader.seek(std::io::SeekFrom::Start(file_addr as u64))?;
|
||||
reader
|
||||
.read_type::<T>(Endian::Little)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
|
||||
} else {
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"Address not found",
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::fs::File> for WindowsPEFile {
|
||||
fn from(file: std::fs::File) -> Self {
|
||||
let mut reader = binrw::io::BufReader::new(&file);
|
||||
let header = reader.read_ne().unwrap();
|
||||
Self { file, header }
|
||||
}
|
||||
}
|
||||
130
flake.lock
generated
Normal file
130
flake.lock
generated
Normal file
@@ -0,0 +1,130 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705309234,
|
||||
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1712883908,
|
||||
"narHash": "sha256-icE1IJE9fHcbDfJ0+qWoDdcBXUoZCcIJxME4lMHwvSM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a0c9e3aee1000ac2bfb0e5b98c94c946a5d180a9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1706487304,
|
||||
"narHash": "sha256-LE8lVX28MV2jWJsidW13D2qrHU/RUUONendL2Q/WlJg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "90f456026d284c22b3e3497be980b2e47d0b28ac",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-overlay": "rust-overlay"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1712973993,
|
||||
"narHash": "sha256-ZJxC6t2K0UAPW+lV+bJ+pAtwbn29eqZQzXLTG54oL+I=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "a497535d074432133b683dda3a1faa8c8ab587ad",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
45
flake.nix
Normal file
45
flake.nix
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
rust-overlay.url = "github:oxalica/rust-overlay";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
rust-overlay,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
overlays = [ (import rust-overlay) ];
|
||||
pkgs = import nixpkgs { inherit system overlays; };
|
||||
rust-bin = pkgs.rust-bin.stable.latest.default.override {
|
||||
extensions = [
|
||||
"rust-src"
|
||||
"rust-std"
|
||||
"clippy"
|
||||
"rust-analyzer"
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
devShell = pkgs.mkShell rec {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
rust-bin
|
||||
pkg-config
|
||||
];
|
||||
buildInputs = with pkgs; [
|
||||
udev
|
||||
alsa-lib
|
||||
vulkan-loader
|
||||
libxkbcommon
|
||||
wayland
|
||||
];
|
||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
7
nucompat/Cargo.toml
Normal file
7
nucompat/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "nucompat"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
binrw = "0.13"
|
||||
0
nucompat/src/lib.rs
Normal file
0
nucompat/src/lib.rs
Normal file
1
nucompat/src/main.rs
Normal file
1
nucompat/src/main.rs
Normal file
@@ -0,0 +1 @@
|
||||
fn main() {}
|
||||
7
wangan_sunrise/Cargo.toml
Normal file
7
wangan_sunrise/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "wangan_sunrise"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bevy = { version = "0.13", features = ["wayland"] }
|
||||
43
wangan_sunrise/src/assets/game_asset_reader.rs
Normal file
43
wangan_sunrise/src/assets/game_asset_reader.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use std::{env, fs::File, path::Path};
|
||||
|
||||
use bevy::{
|
||||
asset::io::{AssetReader, AssetReaderError, Reader},
|
||||
utils::BoxedFuture,
|
||||
};
|
||||
|
||||
struct GameAssetReader(Box<dyn AssetReader>);
|
||||
|
||||
fn get_game_dir() -> String {
|
||||
env::var("GAME_DIR").unwrap_or(".".to_string())
|
||||
}
|
||||
|
||||
impl AssetReader for GameAssetReader {
|
||||
fn read<'a>(
|
||||
&'a self,
|
||||
path: &'a Path,
|
||||
) -> BoxedFuture<'a, Result<Box<Reader<'a>>, AssetReaderError>> {
|
||||
let full_path = path.join(get_game_dir());
|
||||
self.0.read(&full_path)
|
||||
}
|
||||
|
||||
fn read_meta<'a>(
|
||||
&'a self,
|
||||
path: &'a Path,
|
||||
) -> BoxedFuture<'a, Result<Box<Reader<'a>>, AssetReaderError>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn read_directory<'a>(
|
||||
&'a self,
|
||||
path: &'a Path,
|
||||
) -> BoxedFuture<'a, Result<Box<bevy::asset::io::PathStream>, AssetReaderError>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn is_directory<'a>(
|
||||
&'a self,
|
||||
path: &'a Path,
|
||||
) -> BoxedFuture<'a, Result<bool, AssetReaderError>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
1
wangan_sunrise/src/assets/mod.rs
Normal file
1
wangan_sunrise/src/assets/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod game_asset_reader;
|
||||
7
wangan_sunrise/src/main.rs
Normal file
7
wangan_sunrise/src/main.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
mod assets;
|
||||
|
||||
use bevy::{app::App, asset::io::AssetReader, DefaultPlugins};
|
||||
|
||||
fn main() {
|
||||
App::new().add_plugins(DefaultPlugins).run();
|
||||
}
|
||||
Reference in New Issue
Block a user