Updating event handler
This commit is contained in:
@@ -7,5 +7,4 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
easing.c
|
||||
animation.c
|
||||
animationproperty.c
|
||||
)
|
||||
|
||||
@@ -8,86 +8,45 @@
|
||||
#include "util/memory.h"
|
||||
#include "util/math.h"
|
||||
|
||||
void animationInit(animation_t *anim) {
|
||||
memoryZero(anim, sizeof(animation_t));
|
||||
eventInit(&anim->onStart);
|
||||
eventInit(&anim->onComplete);
|
||||
void animationInit(
|
||||
animation_t *anim,
|
||||
keyframe_t *keyframes,
|
||||
uint16_t keyframeCount
|
||||
) {
|
||||
assertNotNull(anim, "Animation pointer cannot be null.");
|
||||
assertNotNull(keyframes, "Keyframes pointer cannot be null.");
|
||||
assertTrue(keyframeCount > 0, "Keyframe count must be more than 0.");
|
||||
|
||||
anim->keyframes = keyframes;
|
||||
anim->keyframeCount = keyframeCount;
|
||||
}
|
||||
|
||||
animationproperty_t *animationAddProperty(animation_t *anim, float_t *target) {
|
||||
assertTrue(
|
||||
anim->propertyCount < ANIMATION_PROPERTY_COUNT_MAX,
|
||||
"Property count exceeds ANIMATION_PROPERTY_COUNT_MAX"
|
||||
);
|
||||
animationproperty_t *prop = &anim->properties[anim->propertyCount++];
|
||||
prop->keyframeCount = 0;
|
||||
prop->target = target;
|
||||
return prop;
|
||||
}
|
||||
float_t animationGetValue(animation_t *anim, const float_t time) {
|
||||
assertNotNull(anim, "Animation pointer cannot be null.");
|
||||
assertNotNull(anim->keyframes, "Keyframes pointer cannot be null.");
|
||||
assertTrue(anim->keyframeCount > 0, "Keyframe count invalid.");
|
||||
assertTrue(time >= 0, "Time must be non-negative.");
|
||||
|
||||
keyframe_t *start;
|
||||
keyframe_t *end;
|
||||
keyframe_t *last = anim->keyframes + anim->keyframeCount - 1;
|
||||
keyframe_t *current = anim->keyframes;
|
||||
start = current;
|
||||
|
||||
void animationUpdate(animation_t *anim, float_t delta) {
|
||||
assertNotNull(anim, "Animation cannot be null");
|
||||
|
||||
if(
|
||||
(anim->flags & ANIMATION_FLAG_FINISHED) &&
|
||||
!(anim->flags & ANIMATION_FLAG_LOOP_ENABLED)
|
||||
) return;
|
||||
|
||||
bool_t wasStarted = (anim->flags & ANIMATION_FLAG_STARTED) != 0;
|
||||
anim->flags |= ANIMATION_FLAG_STARTED;
|
||||
anim->time += delta;
|
||||
|
||||
float_t duration = animationGetDuration(anim);
|
||||
bool_t justFinished = false;
|
||||
if(anim->time >= duration) {
|
||||
if(anim->flags & ANIMATION_FLAG_LOOP_ENABLED) {
|
||||
anim->time = mathModFloat(anim->time, duration);
|
||||
} else {
|
||||
anim->time = duration;
|
||||
if(!(anim->flags & ANIMATION_FLAG_FINISHED)) {
|
||||
anim->flags |= ANIMATION_FLAG_FINISHED;
|
||||
justFinished = true;
|
||||
}
|
||||
do {
|
||||
if(current->time > time) {
|
||||
end = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
start = current;
|
||||
current++;
|
||||
|
||||
for(uint8_t i = 0; i < anim->propertyCount; i++) {
|
||||
animationproperty_t *prop = &anim->properties[i];
|
||||
if(prop->target != NULL) {
|
||||
*prop->target = animationPropertyGetValue(prop, anim->time);
|
||||
if(current > last) {
|
||||
end = start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(true);
|
||||
|
||||
if(!wasStarted) eventInvoke(&anim->onStart, anim);
|
||||
if(justFinished) eventInvoke(&anim->onComplete, anim);
|
||||
}
|
||||
|
||||
|
||||
void animationReset(animation_t *anim) {
|
||||
anim->time = 0.0f;
|
||||
anim->flags &= ~(ANIMATION_FLAG_FINISHED | ANIMATION_FLAG_STARTED);
|
||||
}
|
||||
|
||||
bool_t animationIsFinished(const animation_t *anim) {
|
||||
return (anim->flags & ANIMATION_FLAG_FINISHED) != 0;
|
||||
}
|
||||
|
||||
bool_t animationIsStarted(const animation_t *anim) {
|
||||
return (anim->flags & ANIMATION_FLAG_STARTED) != 0;
|
||||
}
|
||||
|
||||
bool_t animationIsLooping(const animation_t *anim) {
|
||||
return (anim->flags & ANIMATION_FLAG_LOOP_ENABLED) != 0;
|
||||
}
|
||||
|
||||
float_t animationGetDuration(const animation_t *anim) {
|
||||
float_t duration = 0.0f;
|
||||
for(uint8_t i = 0; i < anim->propertyCount; i++) {
|
||||
animationproperty_t *prop = &anim->properties[i];
|
||||
if(prop->keyframeCount == 0) continue;
|
||||
float_t lastKeyframeTime =
|
||||
prop->keyframes[prop->keyframeCount - 1].time;
|
||||
if(lastKeyframeTime > duration) duration = lastKeyframeTime;
|
||||
}
|
||||
return duration;
|
||||
float_t t = (time - start->time) / (end->time - start->time);
|
||||
return mathLerp(start->value, end->value, easingApply(start->easing, t));
|
||||
}
|
||||
@@ -4,87 +4,31 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "animationproperty.h"
|
||||
#include "event/event.h"
|
||||
|
||||
#define ANIMATION_PROPERTY_COUNT_MAX 8
|
||||
|
||||
#define ANIMATION_FLAG_FINISHED (1 << 0)
|
||||
#define ANIMATION_FLAG_STARTED (1 << 1)
|
||||
#define ANIMATION_FLAG_LOOP_ENABLED (1 << 2)
|
||||
#include "keyframe.h"
|
||||
|
||||
typedef struct {
|
||||
animationproperty_t properties[ANIMATION_PROPERTY_COUNT_MAX];
|
||||
uint8_t propertyCount;
|
||||
float_t time;
|
||||
uint8_t flags;
|
||||
event_t onStart;
|
||||
event_t onComplete;
|
||||
keyframe_t *keyframes;
|
||||
uint16_t keyframeCount;
|
||||
} animation_t;
|
||||
|
||||
/**
|
||||
* Initializes an animation.
|
||||
*
|
||||
* @param anim The animation to initialize.
|
||||
* @param keyframes The keyframes to use for the animation.
|
||||
* @param keyframeCount The number of keyframes in the animation.
|
||||
*/
|
||||
void animationInit(animation_t *anim);
|
||||
void animationInit(
|
||||
animation_t *anim,
|
||||
keyframe_t *keyframes,
|
||||
uint16_t keyframeCount
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds a new animated property. The caller owns target and must keep it valid
|
||||
* for the lifetime of the animation.
|
||||
* Gets the value of the animation at a given time.
|
||||
*
|
||||
* @param anim The animation to add the property to.
|
||||
* @param target Pointer to the float to write interpolated values into.
|
||||
* @return A pointer to the new property.
|
||||
* @param anim The animation to get the value from.
|
||||
* @param time The time at which to get the value, in seconds.
|
||||
* @return The value of the animation at the given time.
|
||||
*/
|
||||
animationproperty_t *animationAddProperty(animation_t *anim, float_t *target);
|
||||
|
||||
/**
|
||||
* Advances the animation by delta seconds and writes interpolated values to
|
||||
* each property's target pointer.
|
||||
*
|
||||
* @param anim The animation to update.
|
||||
* @param delta The time to advance the animation by, in seconds.
|
||||
*/
|
||||
void animationUpdate(animation_t *anim, float_t delta);
|
||||
|
||||
/**
|
||||
* Resets the animation to the beginning, clearing Started and Finished flags.
|
||||
*
|
||||
* @param anim The animation to reset.
|
||||
*/
|
||||
void animationReset(animation_t *anim);
|
||||
|
||||
/**
|
||||
* Returns true if the animation has finished (i.e. reached the end of its
|
||||
* duration and is not looping).
|
||||
*
|
||||
* @param anim The animation to check.
|
||||
* @return true if the animation has finished, false otherwise.
|
||||
*/
|
||||
bool_t animationIsFinished(const animation_t *anim);
|
||||
|
||||
/**
|
||||
* Returns true if the animation has been started (i.e. animationUpdate has
|
||||
* been called at least once).
|
||||
*
|
||||
* @param anim The animation to check.
|
||||
* @return true if the animation has been started, false otherwise.
|
||||
*/
|
||||
bool_t animationIsStarted(const animation_t *anim);
|
||||
|
||||
/**
|
||||
* Returns true if the animation is set to loop.
|
||||
*
|
||||
* @param anim The animation to check.
|
||||
* @return true if the animation is set to loop, false otherwise.
|
||||
*/
|
||||
bool_t animationIsLooping(const animation_t *anim);
|
||||
|
||||
/**
|
||||
* Gets the total duration of the animation (based on the keyframes).
|
||||
*
|
||||
* @param anim The animation to get the duration of.
|
||||
* @return The total duration of the animation, in seconds.
|
||||
*/
|
||||
float_t animationGetDuration(const animation_t *anim);
|
||||
float_t animationGetValue(animation_t *anim, const float_t time);
|
||||
@@ -1,55 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "animationproperty.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
void animationPropertyAddKeyframe(
|
||||
animationproperty_t *prop,
|
||||
const float_t time,
|
||||
const float_t value,
|
||||
const easingtype_t easing
|
||||
) {
|
||||
assertNotNull(prop, "Property cannot be null");
|
||||
assertTrue(
|
||||
prop->keyframeCount < ANIMATION_PROPERTY_KEYFRAME_COUNT_MAX,
|
||||
"Too many keyframes added to property"
|
||||
);
|
||||
assertTrue(time >= 0.0f, "Keyframe time cannot be negative");
|
||||
|
||||
keyframe_t *frame = &prop->keyframes[prop->keyframeCount++];
|
||||
frame->time = time;
|
||||
frame->value = value;
|
||||
frame->easing = easing;
|
||||
}
|
||||
|
||||
float_t animationPropertyGetValue(
|
||||
const animationproperty_t *prop,
|
||||
const float_t time
|
||||
) {
|
||||
assertNotNull(prop, "Property cannot be null");
|
||||
assertTrue(time >= 0.0f, "Time cannot be negative");
|
||||
|
||||
if(prop->keyframeCount == 0) return 0.0f;
|
||||
|
||||
uint8_t last = prop->keyframeCount - 1;
|
||||
|
||||
if(prop->keyframeCount == 1) return prop->keyframes[0].value;
|
||||
if(time <= prop->keyframes[0].time) return prop->keyframes[0].value;
|
||||
if(time >= prop->keyframes[last].time) return prop->keyframes[last].value;
|
||||
|
||||
for(uint8_t i = 0; i < last; i++) {
|
||||
const keyframe_t *a = &prop->keyframes[i];
|
||||
const keyframe_t *b = &prop->keyframes[i + 1];
|
||||
if(time < a->time || time >= b->time) continue;
|
||||
float_t t = (time - a->time) / (b->time - a->time);
|
||||
t = easingApply(a->easing, t);
|
||||
return a->value + (b->value - a->value) * t;
|
||||
}
|
||||
|
||||
return prop->keyframes[last].value;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "keyframe.h"
|
||||
|
||||
#define ANIMATION_PROPERTY_KEYFRAME_COUNT_MAX 16
|
||||
|
||||
typedef struct {
|
||||
keyframe_t keyframes[ANIMATION_PROPERTY_KEYFRAME_COUNT_MAX];
|
||||
uint8_t keyframeCount;
|
||||
float_t *target;
|
||||
} animationproperty_t;
|
||||
|
||||
/**
|
||||
* Appends a keyframe to a property. Keyframes must be added in ascending time
|
||||
* order. Updates the animation's duration.
|
||||
*
|
||||
* @param property The property to add the keyframe to.
|
||||
* @param time The time of the keyframe, in seconds.
|
||||
* @param value The value of the keyframe.
|
||||
* @param easing The easing type to use when interpolating to the next keyframe.
|
||||
*/
|
||||
void animationPropertyAddKeyframe(
|
||||
animationproperty_t *property,
|
||||
const float_t time,
|
||||
const float_t value,
|
||||
const easingtype_t easing
|
||||
);
|
||||
|
||||
/**
|
||||
* Gets the property's value at a given time.
|
||||
*
|
||||
* @param prop The property to get the value from.
|
||||
* @param time The time at which to get the value, in seconds.
|
||||
* @return The value of the property at the given time.
|
||||
*/
|
||||
float_t animationPropertyGetValue(
|
||||
const animationproperty_t *prop,
|
||||
const float_t time
|
||||
);
|
||||
@@ -10,4 +10,4 @@ typedef struct {
|
||||
float_t time;
|
||||
float_t value;
|
||||
easingtype_t easing;
|
||||
} keyframe_t;
|
||||
} keyframe_t;
|
||||
+31
-19
@@ -9,43 +9,53 @@
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
void eventInit(event_t *event) {
|
||||
void eventInit(event_t *event, eventcallback_t *callbacks, void **users, size_t size) {
|
||||
assertNotNull(event, "event must not be NULL");
|
||||
memoryZero(event, sizeof(event_t));
|
||||
assertNotNull((void *)callbacks, "callbacks must not be NULL");
|
||||
assertTrue(size > 0, "size must be greater than 0");
|
||||
|
||||
event->callbacks = callbacks;
|
||||
event->users = users;
|
||||
event->size = size;
|
||||
event->count = 0;
|
||||
memoryZero(callbacks, sizeof(eventcallback_t) * size);
|
||||
if(users) memoryZero(users, sizeof(void *) * size);
|
||||
}
|
||||
|
||||
void eventSubscribe(event_t *event, eventcallback_t callback, void *user) {
|
||||
assertNotNull(event, "event must not be NULL");
|
||||
assertNotNull((void *)callback, "callback must not be NULL");
|
||||
assertNotNull(callback, "callback must not be NULL");
|
||||
|
||||
for(uint8_t i = 0; i < event->count; i++) {
|
||||
if(event->callbacks[i] == callback && event->users[i] == user) return;
|
||||
// Ensure callback isn't already susbcribed
|
||||
for(uint32_t i = 0; i < event->count; i++) {
|
||||
if(event->callbacks[i] != callback) continue;
|
||||
assertUnreachable("Callback already registered, cannot subscribe twice.");
|
||||
}
|
||||
|
||||
assertTrue(
|
||||
event->count < EVENT_SUBSCRIBER_COUNT_MAX,
|
||||
"EVENT_SUBSCRIBER_COUNT_MAX exceeded"
|
||||
);
|
||||
assertTrue(event->count < event->size, "event subscriber capacity exceeded");
|
||||
|
||||
event->callbacks[event->count] = callback;
|
||||
event->users[event->count] = user;
|
||||
if(user) {
|
||||
assertNotNull(event->users, "Cannot add user pointer.");
|
||||
event->users[event->count] = user;
|
||||
}
|
||||
event->count++;
|
||||
}
|
||||
|
||||
void eventUnsubscribe(event_t *event, eventcallback_t callback, void *user) {
|
||||
void eventUnsubscribe(event_t *event, eventcallback_t callback) {
|
||||
assertNotNull(event, "event must not be NULL");
|
||||
assertNotNull((void *)callback, "callback must not be NULL");
|
||||
assertNotNull(callback, "callback must not be NULL");
|
||||
|
||||
for(uint8_t i = 0; i < event->count; i++) {
|
||||
if(event->callbacks[i] != callback || event->users[i] != user) continue;
|
||||
for(uint32_t i = 0; i < event->count; i++) {
|
||||
if(event->callbacks[i] != callback) continue;
|
||||
|
||||
uint8_t last = event->count - 1;
|
||||
uint32_t last = event->count - 1;
|
||||
if(i != last) {
|
||||
event->callbacks[i] = event->callbacks[last];
|
||||
event->users[i] = event->users[last];
|
||||
if(event->users) event->users[i] = event->users[last];
|
||||
}
|
||||
event->callbacks[last] = NULL;
|
||||
event->users[last] = NULL;
|
||||
if(event->users) event->users[last] = NULL;
|
||||
event->count--;
|
||||
return;
|
||||
}
|
||||
@@ -53,7 +63,9 @@ void eventUnsubscribe(event_t *event, eventcallback_t callback, void *user) {
|
||||
|
||||
void eventInvoke(const event_t *event, void *params) {
|
||||
assertNotNull(event, "event must not be NULL");
|
||||
for(uint8_t i = 0; i < event->count; i++) {
|
||||
event->callbacks[i](params, event->users[i]);
|
||||
|
||||
for(uint32_t i = 0; i < event->count; i++) {
|
||||
void *u = event->users ? event->users[i] : NULL;
|
||||
event->callbacks[i](params, u);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-13
@@ -8,31 +8,40 @@
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
|
||||
#define EVENT_SUBSCRIBER_COUNT_MAX 8
|
||||
|
||||
typedef void (*eventcallback_t)(void *params, void *user);
|
||||
|
||||
typedef struct {
|
||||
eventcallback_t callbacks[EVENT_SUBSCRIBER_COUNT_MAX];
|
||||
void *users[EVENT_SUBSCRIBER_COUNT_MAX];
|
||||
uint8_t count;
|
||||
eventcallback_t *callbacks;
|
||||
void **users;
|
||||
size_t size;
|
||||
uint32_t count;
|
||||
} event_t;
|
||||
|
||||
/**
|
||||
* Initializes an event, clearing all subscribers.
|
||||
* Initializes an event, binding it to the provided backing arrays and clearing
|
||||
* all subscribers. May also be called to reset an event (re-clears subscribers
|
||||
* without changing the backing arrays or size).
|
||||
*
|
||||
* @param event The event to initialize.
|
||||
* @param callbacks Caller-owned array of at least `size` callback slots.
|
||||
* @param users Array of user pointers, matching each callback, or NULL.
|
||||
* @param size Capacity of both arrays, must match.
|
||||
*/
|
||||
void eventInit(event_t *event);
|
||||
void eventInit(
|
||||
event_t *event,
|
||||
eventcallback_t *callbacks,
|
||||
void **users,
|
||||
size_t size
|
||||
);
|
||||
|
||||
/**
|
||||
* Subscribes a callback to an event. The callback is invoked with params and
|
||||
* the provided user pointer each time the event fires. The same (callback,
|
||||
* user) pair may only be subscribed once.
|
||||
*
|
||||
* @param event The event to subscribe to.
|
||||
* @param event The event to subscribe to.
|
||||
* @param callback The function to call when the event fires.
|
||||
* @param user Arbitrary pointer forwarded to the callback unchanged.
|
||||
* @param user Arbitrary pointer forwarded to the callback unchanged.
|
||||
*/
|
||||
void eventSubscribe(event_t *event, eventcallback_t callback, void *user);
|
||||
|
||||
@@ -40,17 +49,16 @@ void eventSubscribe(event_t *event, eventcallback_t callback, void *user);
|
||||
* Removes a previously subscribed (callback, user) pair. Does nothing if the
|
||||
* pair is not currently subscribed.
|
||||
*
|
||||
* @param event The event to unsubscribe from.
|
||||
* @param event The event to unsubscribe from.
|
||||
* @param callback The callback that was passed to eventSubscribe.
|
||||
* @param user The user pointer that was passed to eventSubscribe.
|
||||
*/
|
||||
void eventUnsubscribe(event_t *event, eventcallback_t callback, void *user);
|
||||
void eventUnsubscribe(event_t *event, eventcallback_t callback);
|
||||
|
||||
/**
|
||||
* Invokes all subscribed callbacks, passing params and each subscriber's user
|
||||
* pointer.
|
||||
*
|
||||
* @param event The event to invoke.
|
||||
* @param event The event to invoke.
|
||||
* @param params Arbitrary pointer forwarded to every callback unchanged.
|
||||
*/
|
||||
void eventInvoke(const event_t *event, void *params);
|
||||
|
||||
@@ -22,8 +22,8 @@ errorret_t inputInit(void) {
|
||||
INPUT.actions[i].action = (inputaction_t)i;
|
||||
INPUT.actions[i].lastValue = 0.0f;
|
||||
INPUT.actions[i].currentValue = 0.0f;
|
||||
eventInit(&INPUT.actions[i].onPressed);
|
||||
eventInit(&INPUT.actions[i].onReleased);
|
||||
eventInit(&INPUT.actions[i].onPressed, INPUT.actions[i].onPressedCallbacks, INPUT.actions[i].onPressedUsers, 4);
|
||||
eventInit(&INPUT.actions[i].onReleased, INPUT.actions[i].onReleasedCallbacks, INPUT.actions[i].onReleasedUsers, 4);
|
||||
}
|
||||
|
||||
#ifdef inputInitPlatform
|
||||
|
||||
@@ -20,7 +20,11 @@ typedef struct {
|
||||
float_t currentDynamicValue;
|
||||
#endif
|
||||
|
||||
eventcallback_t onPressedCallbacks[4];
|
||||
void *onPressedUsers[4];
|
||||
event_t onPressed;
|
||||
eventcallback_t onReleasedCallbacks[4];
|
||||
void *onReleasedUsers[4];
|
||||
event_t onReleased;
|
||||
} inputactiondata_t;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ uifullbox_t UI_FULLBOX_OVER;
|
||||
void uiFullboxInit(uifullbox_t *fullbox) {
|
||||
assertNotNull(fullbox, "fullbox must not be NULL");
|
||||
memoryZero(fullbox, sizeof(uifullbox_t));
|
||||
eventInit(&fullbox->onTransitionEnd);
|
||||
eventInit(&fullbox->onTransitionEnd, fullbox->onTransitionEndCallbacks, fullbox->onTransitionEndUsers, 4);
|
||||
}
|
||||
|
||||
void uiFullboxUpdate(uifullbox_t *fullbox, float_t delta) {
|
||||
|
||||
@@ -17,6 +17,8 @@ typedef struct {
|
||||
float_t duration;
|
||||
float_t time;
|
||||
easingtype_t easing;
|
||||
eventcallback_t onTransitionEndCallbacks[4];
|
||||
void *onTransitionEndUsers[4];
|
||||
event_t onTransitionEnd;
|
||||
} uifullbox_t;
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ uiloading_t UI_LOADING;
|
||||
|
||||
void uiLoadingInit(void) {
|
||||
memoryZero(&UI_LOADING, sizeof(uiloading_t));
|
||||
eventInit(&UI_LOADING.onTransitionEnd);
|
||||
eventInit(&UI_LOADING.onTransitionEnd, UI_LOADING.onTransitionEndCallbacks, UI_LOADING.onTransitionEndUsers, 4);
|
||||
}
|
||||
|
||||
void uiLoadingUpdate(float_t delta) {
|
||||
@@ -65,7 +65,7 @@ static void uiLoadingTransition(
|
||||
UI_LOADING.toAlpha = to;
|
||||
UI_LOADING.duration = UI_LOADING_FADE_DURATION;
|
||||
UI_LOADING.time = 0.0f;
|
||||
eventInit(&UI_LOADING.onTransitionEnd);
|
||||
eventInit(&UI_LOADING.onTransitionEnd, UI_LOADING.onTransitionEndCallbacks, UI_LOADING.onTransitionEndUsers, 4);
|
||||
if(callback) eventSubscribe(&UI_LOADING.onTransitionEnd, callback, user);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ typedef struct {
|
||||
float_t toAlpha;
|
||||
float_t duration;
|
||||
float_t time;
|
||||
eventcallback_t onTransitionEndCallbacks[4];
|
||||
void *onTransitionEndUsers[4];
|
||||
event_t onTransitionEnd;
|
||||
} uiloading_t;
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@ errorret_t uiTextboxInit(void) {
|
||||
UI_TEXTBOX.frame.tileset.uv[1] = 1.0f / 3.0f;
|
||||
UI_TEXTBOX.frame.texture = &TEXTURE_WHITE;
|
||||
|
||||
eventInit(&UI_TEXTBOX.onPageComplete);
|
||||
eventInit(&UI_TEXTBOX.onLastPage);
|
||||
eventInit(&UI_TEXTBOX.onPageComplete, UI_TEXTBOX.onPageCompleteCallbacks, UI_TEXTBOX.onPageCompleteUsers, 4);
|
||||
eventInit(&UI_TEXTBOX.onLastPage, UI_TEXTBOX.onLastPageCallbacks, UI_TEXTBOX.onLastPageUsers, 4);
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,11 @@ typedef struct {
|
||||
int32_t scroll;
|
||||
inputaction_t advanceAction;
|
||||
|
||||
eventcallback_t onPageCompleteCallbacks[4];
|
||||
void *onPageCompleteUsers[4];
|
||||
event_t onPageComplete;
|
||||
eventcallback_t onLastPageCallbacks[4];
|
||||
void *onLastPageUsers[4];
|
||||
event_t onLastPage;
|
||||
} uitextbox_t;
|
||||
|
||||
|
||||
@@ -24,4 +24,8 @@ float_t mathModFloat(float_t x, float_t y) {
|
||||
float_t result = fmodf(x, y);
|
||||
if(result < 0) result += y;
|
||||
return result;
|
||||
}
|
||||
|
||||
float_t mathLerp(float_t a, float_t b, float_t t) {
|
||||
return a + t * (b - a);
|
||||
}
|
||||
+11
-1
@@ -60,4 +60,14 @@ uint32_t mathNextPowTwo(uint32_t value);
|
||||
* @param y The divisor.
|
||||
* @return The result of the modulus operation.
|
||||
*/
|
||||
float_t mathModFloat(float_t x, float_t y);
|
||||
float_t mathModFloat(float_t x, float_t y);
|
||||
|
||||
/**
|
||||
* Linearly interpolates between two values.
|
||||
*
|
||||
* @param a The start value.
|
||||
* @param b The end value.
|
||||
* @param t The interpolation factor, between 0 and 1.
|
||||
* @return The interpolated value.
|
||||
*/
|
||||
float_t mathLerp(float_t a, float_t b, float_t t);
|
||||
Reference in New Issue
Block a user