mirror of
https://github.com/Zelda64Recomp/Zelda64Recomp
synced 2026-06-23 01:20:02 -04:00
Begin implementing mod UI API
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
#include "recomp_ui.h"
|
||||
|
||||
#include "core/ui_context.h"
|
||||
#include "core/ui_resource.h"
|
||||
|
||||
#include "elements/ui_element.h"
|
||||
#include "elements/ui_button.h"
|
||||
#include "elements/ui_clickable.h"
|
||||
#include "elements/ui_container.h"
|
||||
#include "elements/ui_image.h"
|
||||
#include "elements/ui_label.h"
|
||||
#include "elements/ui_radio.h"
|
||||
#include "elements/ui_scroll_container.h"
|
||||
#include "elements/ui_slider.h"
|
||||
#include "elements/ui_style.h"
|
||||
#include "elements/ui_text_input.h"
|
||||
#include "elements/ui_toggle.h"
|
||||
#include "elements/ui_types.h"
|
||||
|
||||
#include "librecomp/overlays.hpp"
|
||||
#include "librecomp/helpers.hpp"
|
||||
|
||||
using namespace recompui;
|
||||
|
||||
constexpr ResourceId root_element_id{ 0xFFFFFFFE };
|
||||
|
||||
// Helpers
|
||||
|
||||
ContextId get_context(uint8_t* rdram, recomp_context* ctx) {
|
||||
uint32_t context_id = _arg<0, uint32_t>(rdram, ctx);
|
||||
return ContextId{ .slot_id = context_id };
|
||||
}
|
||||
|
||||
template <int arg_index>
|
||||
std::string arg_string(uint8_t* rdram, recomp_context* ctx) {
|
||||
PTR(char) str = _arg<arg_index, PTR(char)>(rdram, ctx);
|
||||
|
||||
// Get the length of the byteswapped string.
|
||||
size_t len = 0;
|
||||
while (MEM_B(str, len) != 0x00) {
|
||||
len++;
|
||||
}
|
||||
|
||||
std::string ret{};
|
||||
ret.reserve(len + 1);
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ret += (char)MEM_B(str, i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <int arg_index>
|
||||
ResourceId arg_resource_id(uint8_t* rdram, recomp_context* ctx) {
|
||||
uint32_t slot_id = _arg<arg_index, uint32_t>(rdram, ctx);
|
||||
|
||||
return ResourceId{ .slot_id = slot_id };
|
||||
}
|
||||
|
||||
template <int arg_index>
|
||||
Element* arg_element(uint8_t* rdram, recomp_context* ctx, ContextId ui_context) {
|
||||
ResourceId resource = arg_resource_id<arg_index>(rdram, ctx);
|
||||
|
||||
if (resource == ResourceId::null()) {
|
||||
return nullptr;
|
||||
}
|
||||
else if (resource == root_element_id) {
|
||||
return ui_context.get_root_element();
|
||||
}
|
||||
|
||||
return resource.as_element();
|
||||
}
|
||||
|
||||
template <int arg_index>
|
||||
Style* arg_style(uint8_t* rdram, recomp_context* ctx) {
|
||||
ResourceId resource = arg_resource_id<arg_index>(rdram, ctx);
|
||||
|
||||
if (resource == ResourceId::null()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return *resource;
|
||||
}
|
||||
|
||||
template <int arg_index>
|
||||
Animation arg_animation(uint8_t* rdram, recomp_context* ctx) {
|
||||
PTR(Animation) anim_ptr = _arg<arg_index, PTR(Animation)>(rdram, ctx);
|
||||
|
||||
if (anim_ptr == NULLPTR) {
|
||||
return Animation{};
|
||||
}
|
||||
else {
|
||||
return *TO_PTR(Animation, anim_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void return_resource(recomp_context* ctx, ResourceId resource) {
|
||||
_return<uint32_t>(ctx, resource.slot_id);
|
||||
}
|
||||
|
||||
// Context functions
|
||||
|
||||
extern "C" void recompui_create_context(uint8_t* rdram, recomp_context* ctx) {
|
||||
(void)rdram;
|
||||
ContextId ui_context = create_context();
|
||||
|
||||
_return<uint32_t>(ctx, ui_context.slot_id);
|
||||
}
|
||||
|
||||
extern "C" void recompui_open_context(uint8_t* rdram, recomp_context* ctx) {
|
||||
ContextId ui_context = get_context(rdram, ctx);
|
||||
|
||||
ui_context.open();
|
||||
}
|
||||
|
||||
extern "C" void recompui_close_context(uint8_t* rdram, recomp_context* ctx) {
|
||||
ContextId ui_context = get_context(rdram, ctx);
|
||||
|
||||
ui_context.close();
|
||||
}
|
||||
|
||||
extern "C" void recompui_context_root(uint8_t* rdram, recomp_context* ctx) {
|
||||
ContextId ui_context = get_context(rdram, ctx);
|
||||
(void)ui_context;
|
||||
|
||||
return_resource(ctx, root_element_id);
|
||||
}
|
||||
|
||||
extern "C" void recompui_show_context(uint8_t* rdram, recomp_context* ctx) {
|
||||
ContextId ui_context = get_context(rdram, ctx);
|
||||
|
||||
recompui::show_context(ui_context, "");
|
||||
}
|
||||
|
||||
extern "C" void recompui_hide_context(uint8_t* rdram, recomp_context* ctx) {
|
||||
ContextId ui_context = get_context(rdram, ctx);
|
||||
|
||||
recompui::hide_context(ui_context);
|
||||
}
|
||||
|
||||
// Resource creation functions
|
||||
|
||||
extern "C" void recompui_create_style(uint8_t* rdram, recomp_context* ctx) {
|
||||
ContextId ui_context = get_context(rdram, ctx);
|
||||
|
||||
Style* ret = ui_context.create_style();
|
||||
return_resource(ctx, ret->get_resource_id());
|
||||
}
|
||||
|
||||
extern "C" void recompui_create_element(uint8_t* rdram, recomp_context* ctx) {
|
||||
ContextId ui_context = get_context(rdram, ctx);
|
||||
Element* parent = arg_element<1>(rdram, ctx, ui_context);
|
||||
|
||||
Element* ret = ui_context.create_element<Element>(parent);
|
||||
return_resource(ctx, ret->get_resource_id());
|
||||
}
|
||||
|
||||
extern "C" void recompui_create_button(uint8_t* rdram, recomp_context* ctx) {
|
||||
ContextId ui_context = get_context(rdram, ctx);
|
||||
Element* parent = arg_element<1>(rdram, ctx, ui_context);
|
||||
std::string text = arg_string<2>(rdram, ctx);
|
||||
uint32_t style = _arg<3, uint32_t>(rdram, ctx);
|
||||
|
||||
Button* ret = ui_context.create_element<Button>(parent, text, static_cast<ButtonStyle>(style));
|
||||
return_resource(ctx, ret->get_resource_id());
|
||||
}
|
||||
|
||||
// Style functions
|
||||
|
||||
extern "C" void recompui_set_width(uint8_t* rdram, recomp_context* ctx) {
|
||||
Style* resource = arg_style<0>(rdram, ctx);
|
||||
float width = _arg_float_a1(rdram, ctx);
|
||||
uint32_t unit = _arg<2, uint32_t>(rdram, ctx);
|
||||
Animation animation = arg_animation<3>(rdram, ctx);
|
||||
|
||||
resource->set_width(width, static_cast<Unit>(unit), animation);
|
||||
}
|
||||
|
||||
extern "C" void recompui_set_height(uint8_t* rdram, recomp_context* ctx) {
|
||||
Style* resource = arg_style<0>(rdram, ctx);
|
||||
float height = _arg_float_a1(rdram, ctx);
|
||||
uint32_t unit = _arg<2, uint32_t>(rdram, ctx);
|
||||
Animation animation = arg_animation<3>(rdram, ctx);
|
||||
|
||||
resource->set_height(height, static_cast<Unit>(unit), animation);
|
||||
}
|
||||
|
||||
extern "C" void recompui_set_display(uint8_t* rdram, recomp_context* ctx) {
|
||||
Style* resource = arg_style<0>(rdram, ctx);
|
||||
uint32_t display = _arg<1, uint32_t>(rdram, ctx);
|
||||
|
||||
resource->set_display(static_cast<Display>(display));
|
||||
}
|
||||
|
||||
extern "C" void recompui_set_flex_direction(uint8_t* rdram, recomp_context* ctx) {
|
||||
Style* resource = arg_style<0>(rdram, ctx);
|
||||
uint32_t direction = _arg<1, uint32_t>(rdram, ctx);
|
||||
|
||||
resource->set_flex_direction(static_cast<FlexDirection>(direction));
|
||||
}
|
||||
|
||||
extern "C" void recompui_set_flex_grow(uint8_t* rdram, recomp_context* ctx) { // float grow, Animation animation = Animation()
|
||||
Style* resource = arg_style<0>(rdram, ctx);
|
||||
float grow = _arg_float_a1(rdram, ctx);
|
||||
Animation animation = arg_animation<2>(rdram, ctx);
|
||||
|
||||
resource->set_flex_grow(grow, animation);
|
||||
}
|
||||
|
||||
extern "C" void recompui_set_flex_shrink(uint8_t* rdram, recomp_context* ctx) { // float shrink, Animation animation = Animation()
|
||||
Style* resource = arg_style<0>(rdram, ctx);
|
||||
float shrink = _arg_float_a1(rdram, ctx);
|
||||
Animation animation = arg_animation<2>(rdram, ctx);
|
||||
|
||||
resource->set_flex_shrink(shrink, animation);
|
||||
}
|
||||
|
||||
extern "C" void recompui_set_flex_basis_auto(uint8_t* rdram, recomp_context* ctx) {
|
||||
Style* resource = arg_style<0>(rdram, ctx);
|
||||
|
||||
resource->set_flex_basis_auto();
|
||||
}
|
||||
|
||||
extern "C" void recompui_set_flex_basis(uint8_t* rdram, recomp_context* ctx) { // float basis, Unit unit = Unit::Percent, Animation animation = Animation()
|
||||
Style* resource = arg_style<0>(rdram, ctx);
|
||||
float basis = _arg_float_a1(rdram, ctx);
|
||||
uint32_t unit = _arg<2, uint32_t>(rdram, ctx);
|
||||
Animation animation = arg_animation<3>(rdram, ctx);
|
||||
|
||||
resource->set_flex_basis(basis, static_cast<Unit>(unit), animation);
|
||||
}
|
||||
|
||||
#define REGISTER_FUNC(name) recomp::overlays::register_base_export(#name, name)
|
||||
|
||||
void recompui::register_ui_exports() {
|
||||
REGISTER_FUNC(recompui_create_context);
|
||||
REGISTER_FUNC(recompui_open_context);
|
||||
REGISTER_FUNC(recompui_close_context);
|
||||
REGISTER_FUNC(recompui_context_root);
|
||||
REGISTER_FUNC(recompui_show_context);
|
||||
REGISTER_FUNC(recompui_hide_context);
|
||||
REGISTER_FUNC(recompui_create_style);
|
||||
REGISTER_FUNC(recompui_create_element);
|
||||
REGISTER_FUNC(recompui_create_button);
|
||||
REGISTER_FUNC(recompui_set_width);
|
||||
REGISTER_FUNC(recompui_set_height);
|
||||
REGISTER_FUNC(recompui_set_display);
|
||||
REGISTER_FUNC(recompui_set_flex_direction);
|
||||
REGISTER_FUNC(recompui_set_flex_grow);
|
||||
REGISTER_FUNC(recompui_set_flex_shrink);
|
||||
REGISTER_FUNC(recompui_set_flex_basis_auto);
|
||||
REGISTER_FUNC(recompui_set_flex_basis);
|
||||
}
|
||||
Reference in New Issue
Block a user