mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-20 13:24:40 -04:00
Merge with origin/main
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
* of letting them corrupt memory.
|
||||
*/
|
||||
#define GAME_SERVICE_ID "dev.twilitrealm.dusklight.game"
|
||||
#define GAME_SERVICE_MAJOR 1u
|
||||
#define GAME_SERVICE_MAJOR 2u
|
||||
#define GAME_SERVICE_MINOR 0u
|
||||
|
||||
typedef struct GameService {
|
||||
|
||||
@@ -33,10 +33,68 @@
|
||||
|
||||
#define GFX_SERVICE_ID "dev.twilitrealm.dusklight.gfx"
|
||||
#define GFX_SERVICE_MAJOR 1u
|
||||
#define GFX_SERVICE_MINOR 1u
|
||||
#define GFX_SERVICE_MINOR 2u
|
||||
|
||||
/* Maximum size for push_draw payload */
|
||||
#define GFX_INLINE_DRAW_PAYLOAD_SIZE 128u
|
||||
#define GFX_MAX_COLOR_ATTACHMENTS 8u
|
||||
#define GFX_SCENE_COLOR_ATTACHMENT_INDEX 0u
|
||||
|
||||
typedef enum GfxAttachmentSemantic {
|
||||
GFX_ATTACHMENT_SCENE_COLOR,
|
||||
GFX_ATTACHMENT_NORMAL,
|
||||
GFX_ATTACHMENT_AUXILIARY,
|
||||
} GfxAttachmentSemantic;
|
||||
|
||||
typedef struct GfxColorAttachmentLayout {
|
||||
GfxAttachmentSemantic semantic;
|
||||
WGPUTextureFormat format;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
} GfxColorAttachmentLayout;
|
||||
|
||||
typedef struct GfxRenderTargetLayout {
|
||||
uint32_t struct_size;
|
||||
uint64_t key;
|
||||
/* At least one; scene color is at GFX_SCENE_COLOR_ATTACHMENT_INDEX. */
|
||||
uint32_t color_attachment_count;
|
||||
GfxColorAttachmentLayout color_attachments[GFX_MAX_COLOR_ATTACHMENTS];
|
||||
WGPUTextureFormat depth_stencil_format;
|
||||
uint32_t sample_count;
|
||||
} GfxRenderTargetLayout;
|
||||
|
||||
#define GFX_RENDER_TARGET_LAYOUT_INIT \
|
||||
{sizeof(GfxRenderTargetLayout), 0u, 0u, \
|
||||
{{GFX_ATTACHMENT_AUXILIARY, WGPUTextureFormat_Undefined}}, WGPUTextureFormat_Undefined, \
|
||||
1u}
|
||||
|
||||
/*
|
||||
* Initializes pipeline color targets for a render-target layout. Only scene color is writable;
|
||||
* callers that write another semantic should override that target afterward.
|
||||
*/
|
||||
static uint32_t gfx_init_color_target_states(const GfxRenderTargetLayout* layout,
|
||||
WGPUColorTargetState targets[GFX_MAX_COLOR_ATTACHMENTS], const WGPUBlendState* scene_blend,
|
||||
WGPUColorWriteMask scene_write_mask) {
|
||||
if (layout == NULL || targets == NULL) {
|
||||
return 0;
|
||||
}
|
||||
const uint32_t count = layout->color_attachment_count < GFX_MAX_COLOR_ATTACHMENTS ?
|
||||
layout->color_attachment_count :
|
||||
GFX_MAX_COLOR_ATTACHMENTS;
|
||||
for (uint32_t i = 0; i < GFX_MAX_COLOR_ATTACHMENTS; ++i) {
|
||||
WGPUColorTargetState target = WGPU_COLOR_TARGET_STATE_INIT;
|
||||
if (i < count) {
|
||||
target.format = layout->color_attachments[i].format;
|
||||
target.writeMask = WGPUColorWriteMask_None;
|
||||
}
|
||||
targets[i] = target;
|
||||
}
|
||||
if (count != 0) {
|
||||
targets[GFX_SCENE_COLOR_ATTACHMENT_INDEX].blend = scene_blend;
|
||||
targets[GFX_SCENE_COLOR_ATTACHMENT_INDEX].writeMask = scene_write_mask;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* 0 is never a valid handle. */
|
||||
typedef uint64_t GfxDrawTypeHandle;
|
||||
@@ -51,8 +109,8 @@ typedef struct GfxRange {
|
||||
} GfxRange;
|
||||
|
||||
/*
|
||||
* Device and scene pass configuration. Valid from mod_initialize onward and stable for the
|
||||
* session. Offscreen passes from create_pass are always single-sample.
|
||||
* Device and legacy primary scene-pass configuration. Use get_scene_target_layout when creating
|
||||
* scene pipelines. Offscreen passes from create_pass are always single-sample.
|
||||
*/
|
||||
typedef struct GfxDeviceInfo {
|
||||
uint32_t struct_size;
|
||||
@@ -83,12 +141,18 @@ typedef struct GfxDrawContext {
|
||||
WGPUBuffer index_buffer;
|
||||
WGPUBuffer uniform_buffer;
|
||||
WGPUBuffer storage_buffer;
|
||||
/* deprecated: use layout.color_attachments[GFX_SCENE_COLOR_ATTACHMENT_INDEX].format */
|
||||
WGPUTextureFormat color_format;
|
||||
/* deprecated: use layout.depth_stencil_format */
|
||||
WGPUTextureFormat depth_format;
|
||||
/* deprecated: use layout.sample_count */
|
||||
uint32_t sample_count;
|
||||
/* deprecated: use layout.color_attachments[GFX_SCENE_COLOR_ATTACHMENT_INDEX].width */
|
||||
uint32_t target_width;
|
||||
/* deprecated: use layout.color_attachments[GFX_SCENE_COLOR_ATTACHMENT_INDEX].height */
|
||||
uint32_t target_height;
|
||||
bool uses_reversed_z;
|
||||
GfxRenderTargetLayout layout; /* added in GfxService 1.2 */
|
||||
} GfxDrawContext;
|
||||
|
||||
typedef void (*GfxDrawFn)(ModContext* ctx, const GfxDrawContext* draw_ctx, const void* payload,
|
||||
@@ -269,6 +333,10 @@ typedef struct GfxService {
|
||||
*/
|
||||
ModResult (*push_present)(
|
||||
ModContext* ctx, GfxPresentTargetHandle handle, const void* payload, size_t payload_size);
|
||||
|
||||
/* Minor version 2 */
|
||||
|
||||
ModResult (*get_scene_target_layout)(ModContext* ctx, GfxRenderTargetLayout* out_layout);
|
||||
} GfxService;
|
||||
|
||||
MOD_DECLARE_SERVICE(GfxService, svc_gfx, GFX_SERVICE_ID, GFX_SERVICE_MAJOR, GFX_SERVICE_MINOR);
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
|
||||
#include <mods/api.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <mods/service.hpp>
|
||||
#endif
|
||||
|
||||
#define ITEM_SERVICE_ID "dev.twilitrealm.dusklight.item"
|
||||
#define ITEM_SERVICE_MAJOR 2u
|
||||
#define ITEM_SERVICE_MINOR 0u
|
||||
|
||||
/* 0 is never a valid handle. */
|
||||
typedef uint64_t ItemCheckHandle;
|
||||
typedef uint64_t ItemGiveHandle;
|
||||
|
||||
/*
|
||||
* Item check resolution and inventory grants.
|
||||
*
|
||||
* Check names are case-sensitive. Resolvers must be free of side effects because the game may
|
||||
* resolve a check more than once, including once for display and again when granting the item.
|
||||
* Registrations and pending grants are removed when the calling mod is detached. Callbacks run
|
||||
* on the game thread.
|
||||
*/
|
||||
|
||||
/* Host-owned callback data, valid only for the duration of the callback. */
|
||||
typedef struct ItemCheckInfo {
|
||||
const char* name;
|
||||
const void* giver_actor; /* fopAc_ac_c*, or NULL when unavailable */
|
||||
uint8_t vanilla_item;
|
||||
uint8_t current_item;
|
||||
} ItemCheckInfo;
|
||||
|
||||
/* Return true and write out_item to replace current_item, or false to leave it unchanged. */
|
||||
typedef bool (*ItemCheckResolveFn)(
|
||||
ModContext* ctx, const ItemCheckInfo* info, uint8_t* out_item, void* user_data);
|
||||
|
||||
typedef enum ItemGiveOrigin {
|
||||
ITEM_GIVE_ORIGIN_GAME = 0,
|
||||
ITEM_GIVE_ORIGIN_QUEUE = 1,
|
||||
ITEM_GIVE_ORIGIN_QUEUE_SILENT = 2,
|
||||
} ItemGiveOrigin;
|
||||
|
||||
/* Host-owned callback data, valid only for the duration of the callback. */
|
||||
typedef struct ItemGiveInfo {
|
||||
const char* check_name; /* NULL when the grant is not attributed to a check */
|
||||
const void* giver_actor; /* fopAc_ac_c*, or NULL when unavailable */
|
||||
uint8_t item;
|
||||
uint8_t origin; /* ItemGiveOrigin */
|
||||
} ItemGiveInfo;
|
||||
|
||||
typedef void (*ItemGiveObserveFn)(ModContext* ctx, const ItemGiveInfo* info, void* user_data);
|
||||
|
||||
enum {
|
||||
/* Apply the inventory change without a get-item demo. */
|
||||
ITEM_GIVE_SILENT = 1u << 0,
|
||||
/* Resolve item_no as the named check's vanilla item when the queue entry is dispatched. */
|
||||
ITEM_GIVE_RESOLVE = 1u << 1,
|
||||
};
|
||||
|
||||
typedef struct ItemService {
|
||||
ServiceHeader header;
|
||||
|
||||
/* Set or replace the calling mod's fixed override for name. */
|
||||
ModResult (*set_check_override)(ModContext* ctx, const char* name, uint8_t item_no);
|
||||
|
||||
ModResult (*clear_check_override)(ModContext* ctx, const char* name);
|
||||
|
||||
/* Register for name, or for every check when name is NULL. out_handle may be NULL. */
|
||||
ModResult (*set_check_resolver)(ModContext* ctx, const char* name, ItemCheckResolveFn fn,
|
||||
void* user_data, ItemCheckHandle* out_handle);
|
||||
|
||||
ModResult (*clear_check_resolver)(ModContext* ctx, ItemCheckHandle handle);
|
||||
|
||||
/* Resolve without granting an item or notifying give observers. */
|
||||
ModResult (*resolve_check)(
|
||||
ModContext* ctx, const char* name, uint8_t vanilla_item, uint8_t* out_item);
|
||||
|
||||
/*
|
||||
* Add a grant to the global FIFO. check_name may be NULL unless ITEM_GIVE_RESOLVE is set.
|
||||
* Returns MOD_UNAVAILABLE when the queue is full. Entries wait until gameplay is in a safe
|
||||
* state and are cleared when the active save slot changes.
|
||||
*/
|
||||
ModResult (*give_item)(
|
||||
ModContext* ctx, const char* check_name, uint8_t item_no, uint32_t flags);
|
||||
|
||||
/* Observe inventory grants. out_handle may be NULL. */
|
||||
ModResult (*observe_gives)(
|
||||
ModContext* ctx, ItemGiveObserveFn fn, void* user_data, ItemGiveHandle* out_handle);
|
||||
|
||||
ModResult (*unobserve_gives)(ModContext* ctx, ItemGiveHandle handle);
|
||||
} ItemService;
|
||||
|
||||
MOD_DECLARE_SERVICE(ItemService, svc_item, ITEM_SERVICE_ID, ITEM_SERVICE_MAJOR, ITEM_SERVICE_MINOR);
|
||||
Reference in New Issue
Block a user