mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
197 lines
9.5 KiB
C
197 lines
9.5 KiB
C
#ifndef PSXRECOMP_DUCKSTATION_TEXTURE_PACK_H
|
|
#define PSXRECOMP_DUCKSTATION_TEXTURE_PACK_H
|
|
|
|
#include "hd_texture_pack.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef struct DuckTexturePack DuckTexturePack;
|
|
|
|
enum DuckTextureKind { DUCK_TEXTURE_UPLOAD = 0, DUCK_TEXTURE_PAGE = 1 };
|
|
|
|
/* Independent representation of the modern filename wire format. Source
|
|
* width is in VRAM words; offsets and rectangle sizes are expanded texels.
|
|
* Hashes are unseeded XXH3-64 over explicitly little-endian native words. */
|
|
typedef struct DuckTextureKey {
|
|
uint64_t source_hash;
|
|
uint64_t palette_hash;
|
|
uint16_t source_width_words;
|
|
uint16_t source_height;
|
|
uint16_t offset_x;
|
|
uint16_t offset_y;
|
|
uint16_t width;
|
|
uint16_t height;
|
|
uint8_t kind;
|
|
uint8_t depth; /* enum HdTextureDepth */
|
|
uint8_t semitransparent; /* STP4 / STP8 / STC16 alpha convention */
|
|
uint8_t palette_min;
|
|
uint8_t palette_max;
|
|
} DuckTextureKey;
|
|
|
|
typedef struct DuckTexturePackInfo {
|
|
const char* root;
|
|
const char* diagnostic; /* unsupported config/formats and malformed names */
|
|
size_t replacement_count;
|
|
size_t ambiguous_count;
|
|
size_t ignored_count;
|
|
size_t queued_dump_count; /* Cumulative jobs actually submitted to writer. */
|
|
size_t pending_dump_sources;
|
|
size_t pending_palette_records;
|
|
size_t snapshot_bytes;
|
|
} DuckTexturePackInfo;
|
|
|
|
typedef struct DuckTextureMatch {
|
|
DuckTextureKey key;
|
|
uint64_t entry_id;
|
|
const char* replacement_path;
|
|
/* Origin of replacement rectangle relative to current texture page, in
|
|
* texels. May be negative for uploads spanning more than one page. */
|
|
int32_t origin_u;
|
|
int32_t origin_v;
|
|
uint16_t source_width;
|
|
uint16_t source_height;
|
|
/* Intersection with this draw and the surviving native source region.
|
|
* These page-space texels clip the full replacement mapping above. */
|
|
int32_t clip_u;
|
|
int32_t clip_v;
|
|
uint16_t clip_width;
|
|
uint16_t clip_height;
|
|
} DuckTextureMatch;
|
|
|
|
typedef struct DuckTextureConfig {
|
|
uint16_t max_vram_write_splits;
|
|
uint16_t max_vram_write_coalesce_width;
|
|
uint16_t max_vram_write_coalesce_height;
|
|
uint16_t texture_dump_width_threshold;
|
|
uint16_t texture_dump_height_threshold;
|
|
uint16_t vram_write_dump_width_threshold;
|
|
uint16_t vram_write_dump_height_threshold;
|
|
uint8_t dump_texture_pages;
|
|
uint8_t dump_full_texture_pages;
|
|
uint8_t dump_texture_force_alpha_channel;
|
|
uint8_t dump_vram_write_force_alpha_channel;
|
|
uint8_t dump_c16_textures;
|
|
uint8_t reduce_palette_range;
|
|
uint8_t convert_copies_to_writes;
|
|
uint8_t replacement_scale_linear_filter;
|
|
} DuckTextureConfig;
|
|
|
|
typedef struct DuckTexturePixels {
|
|
const uint8_t* rgba;
|
|
uint32_t width;
|
|
uint32_t height;
|
|
uint32_t stride;
|
|
void* lease;
|
|
} DuckTexturePixels;
|
|
|
|
/* Accepts a game/package folder containing replacements/ and dumps/, or the
|
|
* replacements directory itself. Missing folders are valid empty packs, so
|
|
* a new pack can start by dumping. Recursive image scan; no game assets bundled.
|
|
* PNG, JPEG and WebP payloads; unsupported options and invalid names are
|
|
* diagnosed. Upstream config.yaml keys are root-level scalar options. */
|
|
int duck_texture_pack_create(const char* root, DuckTexturePack** out_pack,
|
|
char* error, size_t error_capacity);
|
|
void duck_texture_pack_destroy(DuckTexturePack* pack);
|
|
void duck_texture_pack_get_info(const DuckTexturePack* pack,
|
|
DuckTexturePackInfo* out_info);
|
|
void duck_texture_pack_get_config(const DuckTexturePack* pack,
|
|
DuckTextureConfig* out_config);
|
|
int duck_texture_pack_linear_filter(const DuckTexturePack* pack);
|
|
uint64_t duck_texture_pack_revision(const DuckTexturePack* pack);
|
|
|
|
int duck_texture_parse_name(const char* filename, DuckTextureKey* out_key);
|
|
int duck_texture_format_name(const DuckTextureKey* key, char* output,
|
|
size_t capacity); /* stem only, without .png */
|
|
uint64_t duck_texture_hash_words_le(const uint16_t* words, size_t count);
|
|
/* Native word rectangle must not wrap. Zero on invalid input (also a valid
|
|
* hash value); use valid geometry rather than zero as a success indication. */
|
|
uint64_t duck_texture_hash_rect(const uint16_t* vram, size_t count,
|
|
uint16_t x, uint16_t y,
|
|
uint16_t width_words, uint16_t height);
|
|
|
|
/* Track post-write native VRAM, after PSX set/check-mask semantics. Wrapped
|
|
* uploads are invalidated but deliberately not tracked. Immutable original
|
|
* words survive partial overwrites and configurable active-region splits. */
|
|
int duck_texture_pack_track_upload(DuckTexturePack* pack,
|
|
uint16_t x, uint16_t y,
|
|
uint16_t width_words, uint16_t height,
|
|
const uint16_t* vram, size_t count);
|
|
void duck_texture_pack_invalidate(DuckTexturePack* pack,
|
|
uint16_t x, uint16_t y,
|
|
uint16_t width_words, uint16_t height);
|
|
void duck_texture_pack_reset_tracking(DuckTexturePack* pack);
|
|
/* Same-session reload only: clone immutable sources and owned observations
|
|
* while the caller keeps native VRAM unchanged. Lookup/image caches remain
|
|
* independent; only same-root filename deduplication history is shared.
|
|
* This is not a savestate restoration API. Strong replacement on success. */
|
|
int duck_texture_pack_copy_tracking(DuckTexturePack* destination,
|
|
const DuckTexturePack* source);
|
|
/* Begin before changing native VRAM, end after PSX mask semantics. Default
|
|
* copies invalidate destination identities. ConvertCopiesToWrites updates an
|
|
* existing destination write's original extent when its active region covers
|
|
* the copy; it does not clone the source upload into the destination. */
|
|
int duck_texture_pack_begin_copy(DuckTexturePack* pack,
|
|
uint16_t source_x, uint16_t source_y,
|
|
uint16_t destination_x, uint16_t destination_y,
|
|
uint16_t width_words, uint16_t height,
|
|
const uint16_t* vram, size_t count);
|
|
int duck_texture_pack_end_copy(DuckTexturePack* pack,
|
|
const uint16_t* vram, size_t count);
|
|
|
|
/* Only one replacement covering the entire inclusive query is accepted.
|
|
* UV wrapping, edge-wrapped pages and multi-image composition fall back.
|
|
* Uses HD_TEXTURE_LOOKUP_* statuses. Query geometry is shared with Beetle. */
|
|
int duck_texture_pack_match(DuckTexturePack* pack,
|
|
const HdTextureDrawQuery* query,
|
|
DuckTextureMatch* out_match);
|
|
/* Prefer ST names on semitransparent primitives and ordinary names otherwise;
|
|
* when only the other convention exists it remains usable. The filename's
|
|
* convention always determines how the renderer interprets its alpha. */
|
|
int duck_texture_pack_match_draw(DuckTexturePack* pack,
|
|
const HdTextureDrawQuery* query,
|
|
int semitransparent, DuckTextureMatch* out_match);
|
|
/* All intersecting parts, in composition order: pages before uploads, larger
|
|
* rectangles before smaller ones. Same-coverage ST variants prefer this draw's
|
|
* convention. An insufficient capacity returns ERROR and zero parts, never a
|
|
* silently truncated composition. At most 64 parts are supported. */
|
|
int duck_texture_pack_match_parts(DuckTexturePack* pack,
|
|
const HdTextureDrawQuery* query,
|
|
int semitransparent,
|
|
DuckTextureMatch* out_matches,
|
|
size_t capacity, size_t* out_count);
|
|
|
|
/* One bounded background worker; no PNG decoding in the render thread.
|
|
* Pixels retain raw DuckStation alpha bytes. The renderer interprets the
|
|
* key.semitransparent flag; this is not conventional opacity for ST names.
|
|
* Release the lease even after pack destruction. */
|
|
void duck_texture_pack_set_decode_budget(DuckTexturePack* pack, size_t bytes);
|
|
int duck_texture_pack_request_decode(DuckTexturePack* pack, uint64_t entry_id);
|
|
int duck_texture_pack_acquire_decoded(DuckTexturePack* pack, uint64_t entry_id,
|
|
DuckTexturePixels* out_pixels);
|
|
void duck_texture_pixels_release(DuckTexturePixels* pixels);
|
|
|
|
/* Records a draw's used region and captured palette, unioning nested crops
|
|
* until the upload/page retires or a flush occurs. Upload-only by default;
|
|
* minimum 16x16, C16 off and reduced palette ranges on. Any semi draw selects
|
|
* ST unless ForceAlpha is enabled. FOUND means new usage was recorded, not
|
|
* that a file was written. Existing files are never overwritten. */
|
|
int duck_texture_pack_dump_draw(DuckTexturePack* pack,
|
|
const HdTextureDrawQuery* query,
|
|
int semitransparent,
|
|
char* error, size_t error_capacity);
|
|
/* Finalize current usage without discarding live identities, then drain dump
|
|
* writes. Call before disabling dumps/changing folders. Reset/destruction also
|
|
* finalize. Reload copies own independent sources and share same-root filename
|
|
* history, so destroying a copied pack never steals the original's records.
|
|
* Returns FOUND on success (including empty flush), ERROR on failure. */
|
|
int duck_texture_pack_flush_dumps(DuckTexturePack* pack,
|
|
char* error, size_t error_capacity);
|
|
void duck_texture_pack_reset_dump(DuckTexturePack* pack);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif
|