Skip to content

Commit

Permalink
Merge branch 'master' into gui-merged
Browse files Browse the repository at this point in the history
  • Loading branch information
pizzart committed Oct 10, 2023
2 parents d971557 + 3a23699 commit ecf4679
Show file tree
Hide file tree
Showing 15 changed files with 874 additions and 111 deletions.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,47 @@ A GUI/CLI utility to work with Zouna BigFiles.

<sup>This repository is a relative of the main [FMTK repository](https://github.com/widberg/fmtk).</sup>

## Support

A checkmark indicates that the game has been tested and is working. An x indicates that the game has not been tested or is not working.

| Year | Game | Platform | Version | Format | Status |
|------|---------------------------------------------------------------------------------|----------|---------|----------|--------|
| 2002 | Jimmy Neutron: Boy Genius - BigSky | | | Kalisto ||
| | SpongeBob SquarePants: Revenge of the Flying Dutchman - BigSky | | | Kalisto ||
| | Spirits & Spells (Castleween) (Mahou no Pumpkin) - Wanadoo | | | Kalisto ||
| 2003 | Super Farm - Asobo | | | Kalisto ||
| 2004 | Sitting Ducks - Asobo | | | Kalisto ||
| | The Mummy: The Animated Series - Asobo | | | Kalisto ||
| 2005 | CT Special Forces: Fire for Effect (Nemesis Strike) - Asobo | | | Asobo1 ||
| | Ratatouille (Prototype) - Asobo | | | Asobo1 ||
| 2006 | Garfield: A Tail of Two Kitties (Garfield 2) - Asobo | | | Asobo1 ||
| | Championsheep Rally - Black Sheep | | | Kalisto ||
| 2007 | Ratatouille - Asobo | | | Asobo2 ||
| | The Ugly Duckling and Me - Black Sheep | | | Kalisto ||
| | En Taxi avec Oui-Oui - Black Sheep | | | Kalisto ||
| 2008 | WALL-E - Asobo | | | Asobo2 ||
| | The Magic Roundabout - Black Sheep | | | Kalisto ||
| | Shaun White Snowboarding/Shaun White Snowboarding: Road Trip - Ubisoft Montreal | | | Ubisoft1 ||
| | Warning: Code De La Route - Black Sheep | | | Kalisto ||
| 2009 | FUEL - Asobo | | | Asobo2 ||
| | Up - Asobo | | | Asobo2 ||
| | Shaun White Snowboarding: World Stage - Ubisoft Montreal | | | Ubisoft1 ||
| 2010 | Toy Story 3 - Asobo | | | Asobo2 ||
| | Racket Sports/Racquet Sports/Racket Sports Party - Asobo | | | Asobo2 ||
| | Happy Neuron Academy - Black Sheep | | | Kalisto ||
| 2012 | Kinect Rush: A Disney-Pixar Adventure - Asobo | | | Asobo3 ||
| 2013 | Super Farm (Re-release) - Asobo | | | Asobo3 ||
| 2014 | Monopoly Plus/Monopoly Deal - Asobo | | | Asobo3 ||
| 2015 | The Mighty Quest for Epic Loot - Ubisoft Montreal | | | Ubisoft2 ||
| 2016 | Young Conker - Asobo | | | Asobo3 ||
| | Fragments - Asobo | | | Asobo3 ||
| 2017 | Rush: A Disney-Pixar Adventure (Re-release) - Asobo | | | Asobo4 ||
| | Monopoly Plus/Monopoly Deal/Monopoly for Nintendo Switch (Re-release) - Asobo | | | Asobo3 ||
| 2019 | A Plague Tale: Innocence - Asobo | | | Asobo5 ||
| 2020 | Microsoft Flight Simulator - Asobo | | | Asobo5 ||
| 2022 | A Plague Tale: Requiem - Asobo | | | Asobo5 ||

## Getting Started

### Prerequisites
Expand Down
6 changes: 3 additions & 3 deletions bff-cli/src/round_trip.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::ffi::OsStr;
use std::fs::File;
use std::path::{Path, PathBuf};
use std::path::Path;

use bff::bigfile::BigFile;

Expand All @@ -9,11 +9,11 @@ use crate::extract::read_bigfile;

pub fn write_bigfile(bigfile_path: &Path, bigfile: &BigFile) -> BffCliResult<()> {
let mut writer = File::create(bigfile_path)?;
// let mut writer = Writer::new(f);
// Intentionally use an unbuffered writer for debugging purposes.
Ok(BigFile::write(bigfile, &mut writer)?)
}

pub fn round_trip(bigfile_path: &PathBuf) -> BffCliResult<()> {
pub fn round_trip(bigfile_path: &Path) -> BffCliResult<()> {
let bigfile = read_bigfile(bigfile_path)?;
let mut new_extension = bigfile_path
.extension()
Expand Down
135 changes: 134 additions & 1 deletion bff-derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::{braced, parse_macro_input, Arm, DeriveInput, Ident, LitStr, Result};
use syn::spanned::Spanned;
use syn::{braced, parse_macro_input, Arm, Data, DeriveInput, Fields, Ident, LitStr, Result};

#[proc_macro_derive(NamedClass)]
pub fn bff_named_class(input: TokenStream) -> TokenStream {
Expand Down Expand Up @@ -249,3 +250,135 @@ fn impl_write_bigfile(input: &BffBigFileMacroInput) -> proc_macro2::TokenStream
}
}
}

#[proc_macro_derive(ReferencedNames)]
pub fn referenced_names(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);
let name = &input.ident;
for param in &mut input.generics.params {
if let syn::GenericParam::Type(ty) = param {
ty.bounds
.push(syn::parse_quote!(crate::traits::ReferencedNames));
}
}
let generics = &mut input.generics;
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();

let body = match input.data {
Data::Struct(data) => match data.fields {
Fields::Named(named) => {
let fields = named
.named
.iter()
.map(|field| {
let name = field.ident.as_ref().unwrap();
quote! {
names.extend(self.#name.names());
}
})
.collect::<Vec<_>>();

quote! {
#(#fields)*
}
}
Fields::Unnamed(unnamed) => {
let fields = unnamed
.unnamed
.iter()
.enumerate()
.map(|(i, _)| {
quote! {
names.extend(self.#i.names());
}
})
.collect::<Vec<_>>();

quote! {
#(#fields)*
}
}
Fields::Unit => {
quote! {}
}
},
Data::Enum(data) => {
let variants = data
.variants
.iter()
.map(|variant| {
let variant_name = &variant.ident;
match &variant.fields {
Fields::Named(named) => {
let (names, fields): (Vec<_>, Vec<_>) = named
.named
.iter()
.map(|field| {
let name = field.ident.as_ref().unwrap();
(
name,
quote! {
names.extend(#name.names());
},
)
})
.unzip();

quote! {
#variant_name { #(#names,)* } => {
#(#fields)*
}
}
}
Fields::Unnamed(unnamed) => {
let (names, fields): (Vec<_>, Vec<_>) = unnamed
.unnamed
.iter()
.enumerate()
.map(|(i, _)| {
let ident =
Ident::new(format!("field_{}", i).as_str(), variant.span());
(
ident,
quote! {
names.extend(ident.names());
},
)
})
.unzip();

quote! {
#variant_name { #(#names,)* } => {
#(#fields)*
}
}
}
Fields::Unit => {
quote! { #variant_name => {} }
}
}
})
.collect::<Vec<_>>();

quote! {
match self {
#(#variants)*
}
}
}
Data::Union(_) => {
unimplemented!()
}
};

quote! {
impl #impl_generics crate::traits::ReferencedNames for #name #ty_generics #where_clause {
fn names(&self) -> std::collections::HashSet<crate::names::Name> {
let mut names = std::collections::HashSet::new();
#body
names
}
}
}
.into()
}
34 changes: 17 additions & 17 deletions bff/src/bigfile/v1_06_63_02_pc/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,38 @@ pub struct BlockDescription {
pub checksum: Option<i32>,
}

#[binread]
#[binrw]
#[derive(Serialize, Debug)]
pub struct Header {
#[br(map = |is_not_rtc: u32| is_not_rtc == 0)]
#[bw(map = |is_rtc: &bool| if *is_rtc { 0u32 } else { 1u32 })]
pub is_rtc: bool,
#[br(temp)]
#[bw(calc = block_descriptions.len() as u32)]
block_count: u32,
block_working_buffer_capacity_even: u32,
block_working_buffer_capacity_odd: u32,
#[br(temp)]
_padded_size: u32,
pub block_working_buffer_capacity_even: u32,
pub block_working_buffer_capacity_odd: u32,
pub padded_size: u32,
pub version_triple: VersionTriple,
#[serde(skip)]
#[br(count = block_count)]
pub block_descriptions: Vec<BlockDescription>,
#[br(temp, seek_before = SeekFrom::Start(0x720))]
_pool_manifest_padded_size: u32,
#[brw(seek_before = SeekFrom::Start(0x720))]
pub pool_manifest_padded_size: u32,
#[br(map = |pool_offset: u32| if pool_offset != u32::MAX && pool_offset != 0 { Some(pool_offset * 2048) } else { None })]
#[bw(map = |pool_offset: &Option<u32>| pool_offset.map(|pool_offset| pool_offset / 2048).unwrap_or(0))]
pub pool_offset: Option<u32>,
#[br(map = |pool_manifest_unused: u32| if pool_manifest_unused != u32::MAX { Some(pool_manifest_unused) } else { None })]
pub pool_manifest_unused: Option<u32>,
#[br(temp)]
#[bw(calc = pool_manifest_unused.unwrap_or(0))]
_pool_manifest_unused1: u32,
#[br(temp)]
_pool_object_decompression_buffer_capacity: u32,
#[br(temp)]
_block_sector_padding_size: u32,
#[br(temp)]
_pool_sector_padding_size: u32,
#[br(temp)]
_file_size: u32,
#[br(try, align_after = 2048)]
#[br(map = |incredi_builder_string: FixedStringNull<128>| Some(incredi_builder_string.into()))]
pub pool_object_decompression_buffer_capacity: u32,
pub block_sector_padding_size: u32,
pub pool_sector_padding_size: u32,
pub file_size: u32,
#[brw(align_after = 2048)]
#[br(try, map = |incredi_builder_string: FixedStringNull<128>| Some(incredi_builder_string.into()))]
#[bw(map = |incredi_builder_string: &Option<String>| incredi_builder_string.as_ref().map(|s| FixedStringNull::<128>::from(s.to_string())).unwrap_or(FixedStringNull::<128>::from(String::new())))]
pub incredi_builder_string: Option<String>,
}
Loading

0 comments on commit ecf4679

Please sign in to comment.