mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-12 12:59:56 +00:00
Added various rustfmt configurations.
Revised documentation of the library and lint opt-out reasons. Moved some module documentation to it's own file due to overflowing the line limit. Fixed several spelling errors.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
//! Interface for converting various structures to and from bytes
|
||||
|
||||
/// Convertions to and from bytes for the game file
|
||||
/// Conversions to and from bytes for the game file
|
||||
pub trait Bytes
|
||||
where
|
||||
Self: Sized,
|
||||
|
||||
28
src/game/card/digimon.md
Normal file
28
src/game/card/digimon.md
Normal file
@@ -0,0 +1,28 @@
|
||||
A digimon card
|
||||
|
||||
This module contains the [`Digimon`] struct, which describes a digimon card.
|
||||
|
||||
# Layout
|
||||
The digimon card has a size of `0x138` bytes, and it's layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ------------------- | ------------------------ | ---------------------- | ----------------------------------------------------------------------------------- |
|
||||
| 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
| 0x15 | 0x2 | `u16` | Unknown | `unknown_15` | |
|
||||
| 0x17 | 0x1 | `u8` | Speciality & Level | `speciality level` | The bottom nibble of this byte is the level, while the top nibble is the speciality |
|
||||
| 0x18 | 0x1 | `u8` | DP | `dp_cost` | |
|
||||
| 0x19 | 0x1 | `u8` | +P | `dp_give` | |
|
||||
| 0x1a | 0x1 | `u8` | Unknown | `unknown_1a` | Is `0` for all digimon |
|
||||
| 0x1b | 0x2 | `u16` | Health | `hp` | |
|
||||
| 0x1d | 0x1c | [`Move`] | Circle Move | `move_circle` | |
|
||||
| 0x39 | 0x1c | [`Move`] | Triangle move | `move_triangle` | |
|
||||
| 0x55 | 0x1c | [`Move`] | Cross move | `move_cross` | |
|
||||
| 0x71 | 0x20 | [`EffectCondition`] | First condition | `effect_conditions[0]` | |
|
||||
| 0x91 | 0x20 | [`EffectCondition`] | Second condition | `effect_conditions[1]` | |
|
||||
| 0xb1 | 0x10 | [`Effect`] | First effect | `effects[0]` | |
|
||||
| 0xc1 | 0x10 | [`Effect`] | Second effect | `effects[1]` | |
|
||||
| 0xd1 | 0x10 | [`Effect`] | Third effect | `effects[2]` | |
|
||||
| 0xe1 | 0x1 | [`CrossMoveEffect`] | Cross move effect | `cross_move_effect` | |
|
||||
| 0xe2 | 0x1 | `u8` | Unknown | `unknown_e2` | |
|
||||
| 0xe3 | 0x1 | [`ArrowColor`] | Effect arrow color | `effect_arrow_color` | |
|
||||
| 0xe4 | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
@@ -1,31 +1,4 @@
|
||||
//! A digimon card
|
||||
//!
|
||||
//! This module contains the [`Digimon`] struct, which describes a digimon card.
|
||||
//!
|
||||
//! # Layout
|
||||
//! The digimon card has a size of `0x138` bytes, and it's layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|---------------------|---------------------------|------------------------|-------------------------------------------------------------------------------------|
|
||||
//! | 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
//! | 0x15 | 0x2 | `u16` | Unknown | `unknown_15` | |
|
||||
//! | 0x17 | 0x1 | `u8` | Speciality & Level | `speciality level` | The bottom nibble of this byte is the level, while the top nibble is the speciality |
|
||||
//! | 0x18 | 0x1 | `u8` | DP | `dp_cost` | |
|
||||
//! | 0x19 | 0x1 | `u8` | +P | `dp_give` | |
|
||||
//! | 0x1a | 0x1 | `u8` | Unknown | `unknown_1a` | Is `0` for all digimon |
|
||||
//! | 0x1b | 0x2 | `u16` | Health | `hp` | |
|
||||
//! | 0x1d | 0x1c | [`Move`] | Circle Move | `move_circle` | |
|
||||
//! | 0x39 | 0x1c | [`Move`] | Triangle move | `move_triangle` | |
|
||||
//! | 0x55 | 0x1c | [`Move`] | Cross move | `move_cross` | |
|
||||
//! | 0x71 | 0x20 | [`EffectCondition`] | First condition | `effect_conditions[0]` | |
|
||||
//! | 0x91 | 0x20 | [`EffectCondition`] | Second condition | `effect_conditions[1]` | |
|
||||
//! | 0xb1 | 0x10 | [`Effect`] | First effect | `effects[0]` | |
|
||||
//! | 0xc1 | 0x10 | [`Effect`] | Second effect | `effects[1]` | |
|
||||
//! | 0xd1 | 0x10 | [`Effect`] | Third effect | `effects[2]` | |
|
||||
//! | 0xe1 | 0x1 | [`CrossMoveEffect`] | Cross move effect | `cross_move_effect` | |
|
||||
//! | 0xe2 | 0x1 | `u8` | Unknown | `unknown_e2` | |
|
||||
//! | 0xe3 | 0x1 | [`ArrowColor`] | Effect arrow color | `effect_arrow_color` | |
|
||||
//! | 0xe4 | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
#![doc(include = "digimon.md")]
|
||||
|
||||
// byteorder
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
@@ -275,9 +248,9 @@ impl Bytes for Digimon {
|
||||
hp: LittleEndian::read_u16(bytes.hp),
|
||||
|
||||
// Moves
|
||||
move_circle: Move::from_bytes(bytes.move_circle).map_err(FromBytesError::MoveCircle)?,
|
||||
move_circle: Move::from_bytes(bytes.move_circle).map_err(FromBytesError::MoveCircle)?,
|
||||
move_triangle: Move::from_bytes(bytes.move_triangle).map_err(FromBytesError::MoveTriangle)?,
|
||||
move_cross: Move::from_bytes(bytes.move_cross).map_err(FromBytesError::MoveCross)?,
|
||||
move_cross: Move::from_bytes(bytes.move_cross).map_err(FromBytesError::MoveCross)?,
|
||||
|
||||
// Effects
|
||||
effect_conditions: [
|
||||
|
||||
12
src/game/card/digivolve.md
Normal file
12
src/game/card/digivolve.md
Normal file
@@ -0,0 +1,12 @@
|
||||
A digivolve card
|
||||
|
||||
This module contains the [`Digivolve`] struct, which describes a digivolve card.
|
||||
|
||||
# Layout
|
||||
The digivolve card has a size of `0x6c` bytes, and it's layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ------------------- | ------------------------ | -------------------- | ------------------------------------------------------------------- |
|
||||
| 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
| 0x15 | 0x3 | `[u8; 3]` | Unknown | `unknown_15` | Probably contains the card effect |
|
||||
| 0x8a | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
@@ -1,15 +1,4 @@
|
||||
//! A digivolve card
|
||||
//!
|
||||
//! This module contains the [`Digivolve`] struct, which describes a digivolve card.
|
||||
//!
|
||||
//! # Layout
|
||||
//! The digivolve card has a size of `0x6c` bytes, and it's layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|---------------------|---------------------------|------------------------|---------------------------------------------------------------------|
|
||||
//! | 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
//! | 0x15 | 0x3 | `[u8; 3]` | Unknown | `unknown_15` | Probably contains the card effect |
|
||||
//! | 0x8a | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
#![doc(include = "digivolve.md")]
|
||||
|
||||
// Crate
|
||||
use crate::game::{util, Bytes};
|
||||
|
||||
18
src/game/card/item.md
Normal file
18
src/game/card/item.md
Normal file
@@ -0,0 +1,18 @@
|
||||
An item card
|
||||
|
||||
This module contains the [`Item`] struct, which describes an item card.
|
||||
|
||||
# Layout
|
||||
The item card has a size of `0xde` bytes, and it's layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ------------------- | ------------------------ | ---------------------- | ------------------------------------------------------------------- |
|
||||
| 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
| 0x15 | 0x4 | `u32` | Unknown | `unknown_15` | |
|
||||
| 0x19 | 0x20 | [`EffectCondition`] | First condition | `effect_conditions[0]` | |
|
||||
| 0x39 | 0x20 | [`EffectCondition`] | Second condition | `effect_conditions[1]` | |
|
||||
| 0x59 | 0x10 | [`Effect`] | First effect | `effects[0]` | |
|
||||
| 0x69 | 0x10 | [`Effect`] | Second effect | `effects[1]` | |
|
||||
| 0x79 | 0x10 | [`Effect`] | Third effect | `effects[2]` | |
|
||||
| 0x89 | 0x1 | [`ArrowColor`] | Effect arrow color | `effect_arrow_color` | |
|
||||
| 0x8a | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
@@ -1,21 +1,4 @@
|
||||
//! An item card
|
||||
//!
|
||||
//! This module contains the [`Item`] struct, which describes an item card.
|
||||
//!
|
||||
//! # Layout
|
||||
//! The item card has a size of `0xde` bytes, and it's layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|---------------------|---------------------------|------------------------|-------------------------------------------------------------------------------------|
|
||||
//! | 0x0 | 0x15 | `[char; 0x15]` | Name | `name` | Null-terminated |
|
||||
//! | 0x15 | 0x4 | `u32` | Unknown | `unknown_15` | |
|
||||
//! | 0x19 | 0x20 | [`EffectCondition`] | First condition | `effect_conditions[0]` | |
|
||||
//! | 0x39 | 0x20 | [`EffectCondition`] | Second condition | `effect_conditions[1]` | |
|
||||
//! | 0x59 | 0x10 | [`Effect`] | First effect | `effects[0]` | |
|
||||
//! | 0x69 | 0x10 | [`Effect`] | Second effect | `effects[1]` | |
|
||||
//! | 0x79 | 0x10 | [`Effect`] | Third effect | `effects[2]` | |
|
||||
//! | 0x89 | 0x1 | [`ArrowColor`] | Effect arrow color | `effect_arrow_color` | |
|
||||
//! | 0x8a | 0x54 | `[[char; 0x15]; 4]` | Effect description lines | `effect_description` | Each line is` 0x15` bytes, split over 4 lines, each null terminated |
|
||||
#![doc(include = "item.md")]
|
||||
|
||||
// byteorder
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
@@ -27,7 +27,7 @@ macro_rules! generate_enum_property_mod
|
||||
// Note: Must have no data
|
||||
$enum_variant_name:ident
|
||||
|
||||
// `Display` convertion name
|
||||
// `Display` conversion name
|
||||
($enum_variant_rename:literal)
|
||||
|
||||
=>
|
||||
@@ -121,7 +121,7 @@ macro_rules! generate_enum_property_mod
|
||||
/// Implements [`Bytes`](crate::game::Bytes) for `Option<E>` where `E`
|
||||
/// is the first argument of this macro and an enum.
|
||||
///
|
||||
/// This is done by suppling a sentinel value which is read/written as `None`.
|
||||
/// This is done by supplying a sentinel value which is read/written as `None`.
|
||||
macro generate_enum_property_option {
|
||||
(
|
||||
$( $enum_name:ty => $sentinel_value:literal ),* $(,)?
|
||||
|
||||
12
src/game/card/property/effect.md
Normal file
12
src/game/card/property/effect.md
Normal file
@@ -0,0 +1,12 @@
|
||||
A digimon's support effect
|
||||
|
||||
This module contains the [`Effect`] struct, which describes a support effect.
|
||||
|
||||
# Layout
|
||||
Each support effect has a size of `0x10` bytes, and it's general layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ------ | ----------- | -------- | ------------------------------------------------------ |
|
||||
| 0x0 | 0x1 | `bool` | Exists | N/A | If `0`, the effect does not exist |
|
||||
| 0x1 | 0x1 | N/A | Effect Type | N/A | Determines which [`Effect`] variant is used. |
|
||||
| 0x2 | 0xe | N/A | Arguments | N/A | The arguments used for the current [`Effect`] variant. |
|
||||
@@ -1,15 +1,4 @@
|
||||
//! A digimon's support effect
|
||||
//!
|
||||
//! This module contains the [`Effect`] struct, which describes a support effect.
|
||||
//!
|
||||
//! # Layout
|
||||
//! Each support effect has a size of `0x10` bytes, and it's general layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|----------------------|---------------------------|------------------------|--------------------------------------------------------|
|
||||
//! | 0x0 | 0x1 | `bool` | Exists | N/A | If `0`, the effect does not exist |
|
||||
//! | 0x1 | 0x1 | N/A | Effect Type | N/A | Determines which [`Effect`] variant is used. |
|
||||
//! | 0x2 | 0xe | N/A | Arguments | N/A | The arguments used for the current [`Effect`] variant. |
|
||||
#![doc(include = "effect.md")]
|
||||
|
||||
// byteorder
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
@@ -23,13 +12,13 @@ use crate::game::{
|
||||
/// A digimon's support effects
|
||||
///
|
||||
/// As this type is wildly volatile in which arguments it uses and from where,
|
||||
/// it is an `enum` with struct variants instead of a struct. This simplifices argument
|
||||
/// it is an `enum` with struct variants instead of a struct. This simplifies argument
|
||||
/// verification and, from a language perspective, makes more sense as an implementation.
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
// TODO: Move this `allow` to the variant once clippy allows
|
||||
#[allow(clippy::pub_enum_variant_names)] // `Effect` on `VoidOpponentSupportEffect` isn't refering to the enum
|
||||
#[allow(clippy::pub_enum_variant_names)] // `Effect` on `VoidOpponentSupportEffect` isn't referring to the enum
|
||||
pub enum Effect {
|
||||
/// Changes a property of either digimon
|
||||
///
|
||||
@@ -75,10 +64,9 @@ pub enum Effect {
|
||||
/// `<temp slot> = <A> + (<B> <op> <C>)`
|
||||
#[serde(rename = "Set temp slot")]
|
||||
SetTempSlot {
|
||||
a: Option<DigimonProperty>,
|
||||
b: Option<DigimonProperty>,
|
||||
c: Option<DigimonProperty>,
|
||||
|
||||
a: Option<DigimonProperty>,
|
||||
b: Option<DigimonProperty>,
|
||||
c: Option<DigimonProperty>,
|
||||
op: EffectOperation,
|
||||
},
|
||||
|
||||
@@ -93,11 +81,10 @@ pub enum Effect {
|
||||
/// - `Dp` -> `Offline`
|
||||
#[serde(rename = "Move cards")]
|
||||
MoveCards {
|
||||
player: PlayerType,
|
||||
source: Slot,
|
||||
player: PlayerType,
|
||||
source: Slot,
|
||||
destination: Slot,
|
||||
|
||||
count: u16,
|
||||
count: u16,
|
||||
},
|
||||
|
||||
/// Shuffles a player's online deck
|
||||
|
||||
19
src/game/card/property/effect_condition.md
Normal file
19
src/game/card/property/effect_condition.md
Normal file
@@ -0,0 +1,19 @@
|
||||
A digimon's effect condition
|
||||
|
||||
This module contains the [`EffectCondition`] struct, which describes a condition for an effect.
|
||||
|
||||
# Layout
|
||||
Each support condition has a size of `0x20` bytes, and it's layout is the following:
|
||||
|
||||
| Offset | Size | Type | Name | Location | Details |
|
||||
| ------ | ---- | ---------------------------- | ----------------- | -------------- | ---------------------------------------------------------------------------------- |
|
||||
| 0x0 | 0x1 | `bool` | Misfire | `misfire` | If the condition throws a misfire when false |
|
||||
| 0x1 | 0x1 | `u8` | | `unknown_1` | Always zero |
|
||||
| 0x2 | 0x1 | [`DigimonProperty`] | Property compare | `property_cmp` | The property to compare to for the condition (or 0 if the condition doesn't exist) |
|
||||
| 0x3 | 0x5 | `[u8; 0x5]` | | `unknown_3` | Unknown |
|
||||
| 0x8 | 0x1 | `DigimonProperty` | Property argument | `arg_property` | Property argument for the comparison |
|
||||
| 0x9 | 0xb | `[u8; 0xb]` | | `unknown_9` | Unknown |
|
||||
| 0x14 | 0x2 | `u16` | Number argument | `arg_num` | Number argument for the comparison |
|
||||
| 0x16 | 0x4 | `[u8; 0x4]` | | `unknown_16` | Unknown |
|
||||
| 0x1a | 0x1 | [`EffectConditionOperation`] | Operation | `operation` | Operation to use for the comparison |
|
||||
| 0x1b | 0x5 | `[u8; 0x5]` | | `unknown_1b` | Unknown |
|
||||
@@ -1,22 +1,4 @@
|
||||
//! A digimon's effect condition
|
||||
//!
|
||||
//! This module contains the [`EffectCondition`] struct, which describes a condition for an effect.
|
||||
//!
|
||||
//! # Layout
|
||||
//! Each support condition has a size of `0x20` bytes, and it's layout is the following:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Location | Details |
|
||||
//! |--------|------|------------------------------|---------------------------|--------------- |------------------------------------------------------------------------------------|
|
||||
//! | 0x0 | 0x1 | `bool` | Misfire | `misfire` | If the condition throws a misfire when false |
|
||||
//! | 0x1 | 0x1 | `u8` | | `unknown_1` | Always zero |
|
||||
//! | 0x2 | 0x1 | [`DigimonProperty`] | Property compare | `property_cmp` | The property to compare to for the condition (or 0 if the condition doesn't exist) |
|
||||
//! | 0x3 | 0x5 | `[u8; 0x5]` | | `unknown_3` | Unknown |
|
||||
//! | 0x8 | 0x1 | `DigimonProperty` | Property argument | `arg_property` | Property argument for the comparation |
|
||||
//! | 0x9 | 0xb | `[u8; 0xb]` | | `unknown_9` | Unknown |
|
||||
//! | 0x14 | 0x2 | `u16` | Number argument | `arg_num` | Number argument for the comparation |
|
||||
//! | 0x16 | 0x4 | `[u8; 0x4]` | | `unknown_16` | Unknown |
|
||||
//! | 0x1a | 0x1 | [`EffectConditionOperation`] | Operation | `operation` | Operation to use for the comparation |
|
||||
//! | 0x1b | 0x5 | `[u8; 0x5]` | | `unknown_1b` | Unknown |
|
||||
#![doc(include = "effect_condition.md")]
|
||||
|
||||
// byteorder
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
@@ -47,9 +29,9 @@ pub struct EffectCondition {
|
||||
operation: EffectConditionOperation,
|
||||
|
||||
// Unknown
|
||||
unknown_1: u8,
|
||||
unknown_3: [u8; 0x5],
|
||||
unknown_9: [u8; 0xb],
|
||||
unknown_1: u8,
|
||||
unknown_3: [u8; 0x5],
|
||||
unknown_9: [u8; 0xb],
|
||||
unknown_16: [u8; 0x4],
|
||||
unknown_1b: [u8; 0x5],
|
||||
}
|
||||
@@ -91,7 +73,7 @@ impl Bytes for EffectCondition {
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
misfire: (*bytes.misfire != 0),
|
||||
misfire: (*bytes.misfire != 0),
|
||||
property_cmp: DigimonProperty::from_bytes(bytes.property_cmp).map_err(FromBytesError::Condition)?,
|
||||
|
||||
arg_property: Option::<DigimonProperty>::from_bytes(bytes.arg_property).map_err(FromBytesError::PropertyArgument)?,
|
||||
@@ -100,9 +82,9 @@ impl Bytes for EffectCondition {
|
||||
|
||||
operation: EffectConditionOperation::from_bytes(bytes.operation).map_err(FromBytesError::Operation)?,
|
||||
|
||||
unknown_1: *bytes.unknown_1,
|
||||
unknown_3: *bytes.unknown_3,
|
||||
unknown_9: *bytes.unknown_9,
|
||||
unknown_1: *bytes.unknown_1,
|
||||
unknown_3: *bytes.unknown_3,
|
||||
unknown_9: *bytes.unknown_9,
|
||||
unknown_16: *bytes.unknown_16,
|
||||
unknown_1b: *bytes.unknown_1b,
|
||||
})
|
||||
@@ -151,7 +133,7 @@ impl Bytes for Option<EffectCondition> {
|
||||
type ToError = <EffectCondition as crate::game::Bytes>::ToError;
|
||||
|
||||
fn from_bytes(bytes: &Self::ByteArray) -> Result<Self, Self::FromError> {
|
||||
// If we have no property comparation, return None
|
||||
// If we have no property comparison, return None
|
||||
if bytes[0x2] == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
@@ -63,8 +63,8 @@ impl Bytes for Move {
|
||||
|
||||
// Return the move
|
||||
Ok(Self {
|
||||
name: util::read_null_ascii_string(bytes.name).map_err(FromBytesError::Name)?.to_ascii_string(),
|
||||
power: LittleEndian::read_u16(bytes.power),
|
||||
name: util::read_null_ascii_string(bytes.name).map_err(FromBytesError::Name)?.to_ascii_string(),
|
||||
power: LittleEndian::read_u16(bytes.power),
|
||||
unknown: LittleEndian::read_u32(bytes.unknown),
|
||||
})
|
||||
}
|
||||
|
||||
34
src/game/card/table.md
Normal file
34
src/game/card/table.md
Normal file
@@ -0,0 +1,34 @@
|
||||
The table of all digimon in the game
|
||||
|
||||
# Details
|
||||
At address [0x216d000](Table::START_ADDRESS) of the game file, the card table begins
|
||||
with a small header of `0xb` and then the table itself.
|
||||
|
||||
# Table Layout
|
||||
The digimon table has a max size of [0x14950](Table::MAX_BYTE_SIZE), but does not
|
||||
necessary use all of this space, but it does follow this layout:
|
||||
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | -------- | --------------- | -------------------- | ----------------------------------------------------------------------- |
|
||||
| 0x0 | 0x4 | u32 | Magic | Always contains the string "0ACD" (= [0x44434130](Table::HEADER_MAGIC)) |
|
||||
| 0x4 | 0x2 | u16 | Number of digimon | |
|
||||
| 0x6 | 0x1 | u8 | Number of items | |
|
||||
| 0x7 | 0x1 | u8 | Number of digivolves | |
|
||||
| 0x8 | variable | \[`CardEntry`\] | Card Entries | A contiguous array of [Card Entry](#card-entry-layout) |
|
||||
|
||||
# Card Entry Layout
|
||||
Each card entry consists of a header of the card
|
||||
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | -------- | ------------------------------------ | --------------- | -------------------------------------------- |
|
||||
| 0x0 | 0x3 | [`Card Header`](#card-header-layout) | Card Header | The card's header |
|
||||
| 0x3 | variable | | Card | Either a [Digimon], [Item] or [Digivolve] |
|
||||
| ... | 0x1 | u8 | Null terminator | A null terminator for the card (must be `0`) |
|
||||
|
||||
# Card Header Layout
|
||||
The card header determines which type of card this card entry has.
|
||||
|
||||
| Offset | Size | Type | Name | Details |
|
||||
| ------ | ---- | ------------ | --------- | ------------------------------------------------ |
|
||||
| 0x0 | 0x2 | u16 | Card id | This card's ID |
|
||||
| 0x2 | 0x1 | [`CardType`] | Card type | The card type ([Digimon], [Item] or [Digivolve]) |
|
||||
@@ -1,42 +1,4 @@
|
||||
//! The table of all digimon in the game
|
||||
//!
|
||||
//! # Details
|
||||
//! At address [0x216d000](Table::START_ADDRESS) of the game file, the card table begins
|
||||
//! with a small header of `0xb` and then the table itself.
|
||||
//!
|
||||
//! # Table Layout
|
||||
//! The digimon table has a max size of [0x14950](Table::MAX_BYTE_SIZE), but does not
|
||||
//! necessary use all of this space, but it does follow this layout:
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Details |
|
||||
//! |--------|----------|-----------------|----------------------|-------------------------------------------------------------------------|
|
||||
//! | 0x0 | 0x4 | u32 | Magic | Always contains the string "0ACD" (= [0x44434130](Table::HEADER_MAGIC)) |
|
||||
//! | 0x4 | 0x2 | u16 | Number of digimon | |
|
||||
//! | 0x6 | 0x1 | u8 | Number of items | |
|
||||
//! | 0x7 | 0x1 | u8 | Number of digivolves | |
|
||||
//! | 0x8 | variable | \[`CardEntry`\] | Card Entries | A contigous array of [Card Entry](#card-entry-layout) |
|
||||
//!
|
||||
//! # Card Entry Layout
|
||||
//! Each card entry consists of a header of the card
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Details |
|
||||
//! |--------|----------|--------------------------------------|-----------------|----------------------------------------------|
|
||||
//! | 0x0 | 0x3 | [`Card Header`](#card-header-layout) | Card Header | The card's header |
|
||||
//! | 0x3 | variable | | Card | Either a [Digimon], [Item] or [Digivolve] |
|
||||
//! | ... | 0x1 | u8 | Null terminator | A null terminator for the card (must be `0`) |
|
||||
//!
|
||||
//! # Card Header Layout
|
||||
//! The card header determines which type of card this card entry has.
|
||||
//!
|
||||
//! | Offset | Size | Type | Name | Details |
|
||||
//! |--------|------|--------------|-----------|--------------------------------------------------|
|
||||
//! | 0x0 | 0x2 | u16 | Card id | This card's ID |
|
||||
//! | 0x2 | 0x1 | [`CardType`] | Card type | The card type ([Digimon], [Item] or [Digivolve]) |
|
||||
|
||||
// Lints
|
||||
// False positive, we don't use any `unsafe` in impls
|
||||
// TODO: Remove this lint once it no longer triggers.
|
||||
#![allow(clippy::unsafe_derive_deserialize)]
|
||||
#![doc(include = "table.md")]
|
||||
|
||||
// Std
|
||||
use std::io::{Read, Seek, Write};
|
||||
@@ -121,15 +83,15 @@ pub enum DeserializeError {
|
||||
Table::MAX_BYTE_SIZE
|
||||
)]
|
||||
TooManyCards {
|
||||
digimon_cards: usize,
|
||||
item_cards: usize,
|
||||
digimon_cards: usize,
|
||||
item_cards: usize,
|
||||
digivolve_cards: usize,
|
||||
},
|
||||
|
||||
/// Unable to read card header
|
||||
#[display(fmt = "Unable to read card header for card id {}", id)]
|
||||
ReadCardHeader {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -137,7 +99,7 @@ pub enum DeserializeError {
|
||||
/// An unknown card type was found
|
||||
#[display(fmt = "Unknown card type for card id {}", id)]
|
||||
UnknownCardType {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: property::card_type::FromBytesError,
|
||||
},
|
||||
@@ -145,7 +107,7 @@ pub enum DeserializeError {
|
||||
/// Unable to read a card
|
||||
#[display(fmt = "Unable to read {} with id {}", card_type, id)]
|
||||
ReadCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
card_type: CardType,
|
||||
|
||||
#[error(source)]
|
||||
@@ -155,7 +117,7 @@ pub enum DeserializeError {
|
||||
/// Unable to deserialize a digimon card
|
||||
#[display(fmt = "Unable to deserialize digimon card with id {}", id)]
|
||||
DigimonCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::digimon::FromBytesError,
|
||||
},
|
||||
@@ -163,7 +125,7 @@ pub enum DeserializeError {
|
||||
/// Unable to deserialize an item card
|
||||
#[display(fmt = "Unable to deserialize item card with id {}", id)]
|
||||
ItemCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::item::FromBytesError,
|
||||
},
|
||||
@@ -171,7 +133,7 @@ pub enum DeserializeError {
|
||||
/// Unable to deserialize a digivolve card
|
||||
#[display(fmt = "Unable to deserialize digivolve card with id {}", id)]
|
||||
DigivolveCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::digivolve::FromBytesError,
|
||||
},
|
||||
@@ -179,7 +141,7 @@ pub enum DeserializeError {
|
||||
/// Unable to read card footer
|
||||
#[display(fmt = "Unable to read card footer for card id {}", id)]
|
||||
ReadCardFooter {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -209,15 +171,15 @@ pub enum SerializeError {
|
||||
Table::MAX_BYTE_SIZE
|
||||
)]
|
||||
TooManyCards {
|
||||
digimon_cards: usize,
|
||||
item_cards: usize,
|
||||
digimon_cards: usize,
|
||||
item_cards: usize,
|
||||
digivolve_cards: usize,
|
||||
},
|
||||
|
||||
/// Unable to write a digimon card
|
||||
#[display(fmt = "Unable to write digimon card with id {}", id)]
|
||||
WriteDigimonCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -225,7 +187,7 @@ pub enum SerializeError {
|
||||
/// Unable to write an item card
|
||||
#[display(fmt = "Unable to write item card with id {}", id)]
|
||||
WriteItemCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -233,7 +195,7 @@ pub enum SerializeError {
|
||||
/// Unable to write a digivolve card
|
||||
#[display(fmt = "Unable to write digivolve card with id {}", id)]
|
||||
WriteDigivolveCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -241,7 +203,7 @@ pub enum SerializeError {
|
||||
/// Unable to parse a digimon card
|
||||
#[display(fmt = "Unable to parse digimon card with id {}", id)]
|
||||
ParseDigimonCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::digimon::ToBytesError,
|
||||
},
|
||||
@@ -249,7 +211,7 @@ pub enum SerializeError {
|
||||
/// Unable to parse an item card
|
||||
#[display(fmt = "Unable to parse item card with id {}", id)]
|
||||
ParseItemCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::item::ToBytesError,
|
||||
},
|
||||
@@ -257,7 +219,7 @@ pub enum SerializeError {
|
||||
/// Unable to parse a digivolve card
|
||||
#[display(fmt = "Unable to parse digivolve card with id {}", id)]
|
||||
ParseDigivolveCard {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: card::digivolve::ToBytesError,
|
||||
},
|
||||
@@ -373,8 +335,8 @@ impl Table {
|
||||
// If the total table size is bigger than the max, return Err
|
||||
if table_size > Self::MAX_BYTE_SIZE {
|
||||
return Err(SerializeError::TooManyCards {
|
||||
digimon_cards: self.digimons.len(),
|
||||
item_cards: self.items.len(),
|
||||
digimon_cards: self.digimons.len(),
|
||||
item_cards: self.items.len(),
|
||||
digivolve_cards: self.digivolves.len(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ impl Bytes for Deck {
|
||||
unknown: [0xc],
|
||||
);
|
||||
|
||||
// Nanme / Owner
|
||||
// Name / Owner
|
||||
util::write_maybe_null_ascii_string(&self.name, bytes.name).map_err(ToBytesError::Name)?;
|
||||
util::write_maybe_null_ascii_string(&self.owner, bytes.owner).map_err(ToBytesError::Owner)?;
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ pub enum DeserializeError {
|
||||
/// Could not read a deck entry
|
||||
#[display(fmt = "Unable to read deck entry with id {}", "id")]
|
||||
ReadDeck {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
@@ -50,7 +50,7 @@ pub enum DeserializeError {
|
||||
/// Could not deserialize a deck entry
|
||||
#[display(fmt = "Unable to serialize deck entry with id {}", "id")]
|
||||
DeserializeDeck {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: deck::FromBytesError,
|
||||
},
|
||||
@@ -71,7 +71,7 @@ pub enum SerializeError {
|
||||
/// Could not deserialize a deck entry
|
||||
#[display(fmt = "Unable to deserialize deck entry with id {}", "id")]
|
||||
SerializeDeck {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: deck::ToBytesError,
|
||||
},
|
||||
@@ -79,7 +79,7 @@ pub enum SerializeError {
|
||||
/// Could not write a deck entry
|
||||
#[display(fmt = "Unable to read deck entry with id {}", "id")]
|
||||
WriteDeck {
|
||||
id: usize,
|
||||
id: usize,
|
||||
#[error(source)]
|
||||
err: std::io::Error,
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! This modules is used for miscellaneous macros, functions that have
|
||||
//! not been moved to a more permanent location.
|
||||
//!
|
||||
//! All items in this module will eventually be depracated and moved
|
||||
//! All items in this module will eventually be deprecated and moved
|
||||
//! somewhere else, but this change might take some time.
|
||||
|
||||
pub macro array_split {
|
||||
@@ -170,7 +170,7 @@ pub fn write_null_ascii_string<'a>(input: &ascii::AsciiStr, buf: &'a mut [u8]) -
|
||||
// If the input string doesn't fit into the buffer (excluding the null byte), return Err
|
||||
if input.len() >= buf.len() {
|
||||
return Err(WriteNullAsciiStringError::TooLarge {
|
||||
input_len: input.len(),
|
||||
input_len: input.len(),
|
||||
buffer_len: buf.len(),
|
||||
});
|
||||
}
|
||||
@@ -198,7 +198,7 @@ pub fn write_maybe_null_ascii_string<'a>(input: &ascii::AsciiStr, buf: &'a mut [
|
||||
// If the input string doesn't fit into the buffer, return Err
|
||||
if input.len() > buf.len() {
|
||||
return Err(WriteMaybeNullAsciiStringError::TooLarge {
|
||||
input_len: input.len(),
|
||||
input_len: input.len(),
|
||||
buffer_len: buf.len(),
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user