mirror of
https://github.com/doldecomp/melee.git
synced 2026-11-10 17:10:37 -10:00
178 lines
7.5 KiB
C
178 lines
7.5 KiB
C
/** @file Shared storage and reference operations for generated readers. */
|
|
#ifndef DAT_READER_INTERNAL_H
|
|
#define DAT_READER_INTERNAL_H
|
|
#include <limits.h>
|
|
#include <math.h>
|
|
|
|
#include <dat/archive-data.h>
|
|
#include <dat/archive.h>
|
|
/// Maximum macro expansion depth, matching the Rust evaluator.
|
|
#define MACRO_DEPTH 16
|
|
typedef enum DatIssueKind {
|
|
ISSUE_UNRELOCATED_POINTER,
|
|
ISSUE_RELOCATED_SCALAR,
|
|
ISSUE_OUT_OF_BOUNDS,
|
|
ISSUE_AMBIGUOUS_UNION,
|
|
ISSUE_UNKNOWN_COMMAND,
|
|
} DatIssueKind;
|
|
|
|
/// Individual native allocations, released with the archive.
|
|
typedef struct DatAllocation {
|
|
struct DatAllocation* next;
|
|
void* data;
|
|
} DatAllocation;
|
|
|
|
struct DatArchive {
|
|
const DatSchema* s;
|
|
DatArchiveData* archive;
|
|
Bits object, script;
|
|
/// (offset, type id) visited, as the walk's `visited`.
|
|
DatMap visited;
|
|
/// (offset, type id) → native object.
|
|
DatMap natives;
|
|
/// Native arrays' allocated element counts.
|
|
DatMap native_counts;
|
|
/// Native pointer slots → (target offset, type id), for array aliases.
|
|
DatMap references;
|
|
/// Serialized extern slot → native address supplied by the game.
|
|
DatMap extern_values;
|
|
uint8_t native_moved;
|
|
#ifdef DAT_NATIVE_TESTING
|
|
struct DatValidation* validation;
|
|
#endif
|
|
const DatScope* env;
|
|
/// Names the walk treats specially.
|
|
int32_t name_index, name_command;
|
|
DatAllocation* allocations;
|
|
};
|
|
|
|
typedef enum DatMode {
|
|
/// `DAT_COUNT`: the record's fields, then bindings.
|
|
MODE_COUNT,
|
|
/// `DAT_IF`: the parent record's fields, then those of the union's
|
|
/// record members, then bindings.
|
|
MODE_IF,
|
|
/// `DAT_BIND`: `_index`, the record's fields, then the bindings outside.
|
|
MODE_BIND,
|
|
/// `DAT_TERMINATED`: bindings.
|
|
MODE_TERMINATOR,
|
|
/// A script's command length: `_command`.
|
|
MODE_SCRIPT,
|
|
} DatMode;
|
|
|
|
typedef struct DatContext {
|
|
DatMode mode;
|
|
/// The record the fields are of, and where it is.
|
|
int32_t record;
|
|
uint32_t base;
|
|
/// MODE_IF: the union.
|
|
int32_t onion;
|
|
uint32_t union_base;
|
|
const DatScope* env;
|
|
uint64_t index, command;
|
|
} DatContext;
|
|
|
|
typedef struct DatParent {
|
|
int32_t record;
|
|
uint32_t base;
|
|
uint8_t some;
|
|
} DatParent;
|
|
|
|
typedef enum DatChoiceKind {
|
|
CHOICE_MEMBER,
|
|
CHOICE_UNUSED,
|
|
CHOICE_AMBIGUOUS,
|
|
} DatChoiceKind;
|
|
|
|
uint32_t dat_reader_word(const DatArchive* a, uint64_t offset);
|
|
uint64_t dat_reader_bytes_at(const DatArchive* a, uint64_t offset,
|
|
uint32_t size);
|
|
const DatType* dat_reader_T(const DatArchive* a, int32_t type);
|
|
int32_t dat_reader_resolve(const DatArchive* a, int32_t type);
|
|
int32_t dat_reader_pointee(const DatArchive* a, int32_t target);
|
|
uint32_t dat_reader_native_size(const DatArchive* a, int32_t type);
|
|
uint64_t dat_reader_extend(uint64_t v, uint32_t bits, uint8_t is_signed);
|
|
/// Primitive source widths and signedness are literals emitted by Rust.
|
|
void dat_reader_integer(const DatArchive* a, uint32_t offset,
|
|
uint32_t source_size, uint32_t native_size,
|
|
uint8_t is_signed, void* native);
|
|
void dat_reader_float(const DatArchive* a, uint32_t offset,
|
|
uint32_t source_size, uint32_t native_size,
|
|
void* native);
|
|
uint64_t dat_reader_bits_at(const DatArchive* a, uint64_t offset,
|
|
uint64_t start, uint32_t bits);
|
|
void dat_reader_store_pointer(void* slot, const void* p);
|
|
/// externs (which the loader leaves null), -1 kept as -1, and anything else
|
|
/// as its value.
|
|
void dat_reader_store_unrelocated(DatArchive* a, uint32_t offset,
|
|
uint32_t value, void* slot);
|
|
void* dat_reader_unrelocated_value(const DatArchive* a, uint32_t offset,
|
|
uint32_t value);
|
|
void dat_reader_convert(DatArchive* a, uint32_t offset, int32_t type,
|
|
void* native);
|
|
int dat_reader_field_value(const DatArchive* a, int32_t record, uint32_t base,
|
|
int32_t name, uint64_t* out);
|
|
int dat_reader_resolve_name(const DatArchive* a, const DatContext* c,
|
|
int32_t name, uint64_t* out);
|
|
int dat_reader_col_anim_command_length(uint64_t command, uint64_t* out);
|
|
uint64_t dat_reader_cpu_command_length(uint64_t command);
|
|
int dat_reader_it_command_length(uint64_t command, uint64_t* out);
|
|
int dat_reader_gx_get_tex_buffer_size(uint16_t width, uint16_t height,
|
|
uint32_t format, uint8_t mipmap,
|
|
uint8_t max_lod, uint64_t* out);
|
|
int dat_reader_eval_at(const DatArchive* a, const DatContext* c,
|
|
const DatExpr* e, unsigned depth, uint64_t* out);
|
|
int dat_reader_eval(const DatArchive* a, const DatContext* c, const DatExpr* e,
|
|
uint64_t* out);
|
|
void* dat_reader_native_of(const DatArchive* a, uint32_t offset, int32_t r);
|
|
void dat_reader_place_native(DatArchive* a, uint32_t offset, int32_t r,
|
|
void* native);
|
|
void dat_reader_reference(DatArchive* a, void* slot, uint32_t offset,
|
|
int32_t r);
|
|
void dat_reader_unrelocated(DatArchive* a, uint32_t offset, uint32_t value);
|
|
void dat_reader_read_object(DatArchive* a, uint32_t offset, int32_t type,
|
|
const DatScope* env, void* native, void** slot);
|
|
const DatScope* dat_reader_bind_scope(DatArchive* a, const DatScope* outer,
|
|
DatBinding binding, DatParent parent,
|
|
uint64_t index, DatScope* storage);
|
|
int dat_reader_fits(const DatArchive* a, uint32_t offset, int32_t type);
|
|
int dat_reader_array_count_fits(const DatArchive* a, uint32_t offset,
|
|
int32_t array, int32_t element,
|
|
uint64_t count);
|
|
void dat_reader_counted(DatArchive* a, uint32_t offset, int32_t pointer,
|
|
int32_t element, uint64_t count, DatBinding binding,
|
|
DatScope* storage, DatParent parent, void* slot);
|
|
void dat_reader_terminated(DatArchive* a, uint32_t offset, int32_t pointer,
|
|
void* slot, const DatExpr* terminator,
|
|
uint32_t length);
|
|
uint64_t dat_reader_extent_bound(const DatArchive* a, uint32_t offset,
|
|
uint32_t size);
|
|
void dat_reader_extent(DatArchive* a, uint32_t offset, int32_t array,
|
|
DatBinding binding, DatScope* storage, DatParent parent,
|
|
void* native);
|
|
void dat_reader_typed(DatArchive* a, uint32_t offset, int32_t target,
|
|
void* native, uint32_t native_field);
|
|
void dat_reader_script(DatArchive* a, uint32_t offset, int32_t pointer,
|
|
const DatScript* s, void* slot);
|
|
void dat_reader_layout(DatArchive* a, uint32_t offset, int32_t type,
|
|
void* native, DatParent parent);
|
|
int dat_reader_read_field(const DatArchive* a, uint64_t at, uint32_t size,
|
|
uint8_t floating, uint64_t* out);
|
|
#ifdef DAT_NATIVE_TESTING
|
|
#include <dat/test-internal.h>
|
|
#else
|
|
#define dat_test_init(...) ((void) 0)
|
|
#define dat_test_close(...) ((void) 0)
|
|
#define dat_test_reached(...) ((void) 0)
|
|
#define dat_test_count(...) ((void) 0)
|
|
#define dat_test_sentinel(...) ((void) 0)
|
|
#define dat_reader_mark_pointer(...) ((void) 0)
|
|
#define dat_reader_issue(...) ((void) 0)
|
|
#define dat_reader_record_extent(...) ((void) 0)
|
|
#define dat_reader_typed_extent(...) ((void) 0)
|
|
#define dat_reader_untyped(...) ((void) 0)
|
|
#define dat_reader_relocated_words(...) ((void) 0)
|
|
#define dat_reader_record_choice(...) ((void) 0)
|
|
#endif
|
|
#endif
|