Compare commits
2 Commits
4d74b5e3e9
...
c8e6c320f1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c8e6c320f1 | ||
![]() |
3bb8a63ee1 |
34
src/k3.c
34
src/k3.c
@ -12,6 +12,7 @@
|
|||||||
#include<cglm/vec2.h>
|
#include<cglm/vec2.h>
|
||||||
#include<cglm/frustum.h>
|
#include<cglm/frustum.h>
|
||||||
#include<cglm/cam.h>
|
#include<cglm/cam.h>
|
||||||
|
#include<cglm/box.h>
|
||||||
|
|
||||||
#include"ssort.h"
|
#include"ssort.h"
|
||||||
|
|
||||||
@ -1309,9 +1310,22 @@ static void apply_cpu_skinning(struct k3Mdl *mdl, struct k3AnimationBone *bones)
|
|||||||
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, mdl->offV, mdl->verts * sizeof(*boned), boned);
|
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, mdl->offV, mdl->verts * sizeof(*boned), boned);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void forward_subpass(mat4 view, int transparent, int lightsStart, int lightsCount, size_t rbleStart, size_t rbleEnd) {
|
static bool outside_frustum(vec3 *aabb, float *modelmat, vec4 *frustum) {
|
||||||
|
vec3 transformedAABB[2];
|
||||||
|
glm_aabb_transform(aabb, modelmat, transformedAABB);
|
||||||
|
|
||||||
|
return !glm_aabb_frustum(transformedAABB, frustum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void forward_subpass(mat4 projection, mat4 view, int transparent, int lightsStart, int lightsCount, size_t rbleStart, size_t rbleEnd) {
|
||||||
setup_ff_lights(view, lightsStart, lightsCount);
|
setup_ff_lights(view, lightsStart, lightsCount);
|
||||||
|
|
||||||
|
mat4 viewProj;
|
||||||
|
glm_mat4_mul(projection, view, viewProj);
|
||||||
|
|
||||||
|
vec4 cameraFrustum[6];
|
||||||
|
glm_frustum_planes(viewProj, cameraFrustum);
|
||||||
|
|
||||||
GLhandleARB lastGLSL = -1;
|
GLhandleARB lastGLSL = -1;
|
||||||
GLuint lastVP = 0, lastFP = 0;
|
GLuint lastVP = 0, lastFP = 0;
|
||||||
struct k3Mat *lastMaterial = NULL;
|
struct k3Mat *lastMaterial = NULL;
|
||||||
@ -1327,6 +1341,10 @@ static void forward_subpass(mat4 view, int transparent, int lightsStart, int lig
|
|||||||
GLuint arbvp = renderQueue[rble].arbvp;
|
GLuint arbvp = renderQueue[rble].arbvp;
|
||||||
GLuint arbfp = renderQueue[rble].arbfp;
|
GLuint arbfp = renderQueue[rble].arbfp;
|
||||||
|
|
||||||
|
if(outside_frustum(mdl->aabb, modelmat, cameraFrustum)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
struct k3Mat *mat = &mesh->mat;
|
struct k3Mat *mat = &mesh->mat;
|
||||||
|
|
||||||
if(mat->passes[0].additive && lightsStart != 0) {
|
if(mat->passes[0].additive && lightsStart != 0) {
|
||||||
@ -1535,7 +1553,7 @@ void k3PassForward(mat4 projection, mat4 cam) {
|
|||||||
|
|
||||||
int l = 0, k = LightCount;
|
int l = 0, k = LightCount;
|
||||||
while(1) {
|
while(1) {
|
||||||
forward_subpass(view, 0, l, k > 4 ? 4 : k, 0, renderQueueSize);
|
forward_subpass(projection, view, 0, l, k > 4 ? 4 : k, 0, renderQueueSize);
|
||||||
|
|
||||||
l += 4;
|
l += 4;
|
||||||
k -= 4;
|
k -= 4;
|
||||||
@ -1549,7 +1567,7 @@ void k3PassForward(mat4 projection, mat4 cam) {
|
|||||||
for(size_t rble = 0; rble < renderQueueSize; rble++) {
|
for(size_t rble = 0; rble < renderQueueSize; rble++) {
|
||||||
l = 0, k = LightCount;
|
l = 0, k = LightCount;
|
||||||
while(1) {
|
while(1) {
|
||||||
forward_subpass(view, 1, l, k > 4 ? 4 : k, rble, rble + 1);
|
forward_subpass(projection, view, 1, l, k > 4 ? 4 : k, rble, rble + 1);
|
||||||
|
|
||||||
l += 4;
|
l += 4;
|
||||||
k -= 4;
|
k -= 4;
|
||||||
@ -1573,6 +1591,12 @@ void k3PassDepthOnly(mat4 projection, mat4 cam, int clear, int cull) {
|
|||||||
|
|
||||||
setup_arbprog_globals();
|
setup_arbprog_globals();
|
||||||
|
|
||||||
|
mat4 viewProj;
|
||||||
|
glm_mat4_mul(projection, view, viewProj);
|
||||||
|
|
||||||
|
vec4 cameraFrustum[6];
|
||||||
|
glm_frustum_planes(viewProj, cameraFrustum);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
@ -1608,6 +1632,10 @@ void k3PassDepthOnly(mat4 projection, mat4 cam, int clear, int cull) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(outside_frustum(mdl->aabb, modelmat, cameraFrustum)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
GLhandleARB glsl = renderQueue[rble].glsl;
|
GLhandleARB glsl = renderQueue[rble].glsl;
|
||||||
GLuint arbvp = renderQueue[rble].arbvp;
|
GLuint arbvp = renderQueue[rble].arbvp;
|
||||||
|
|
||||||
|
118
src/k3menu.c
118
src/k3menu.c
@ -3,6 +3,78 @@
|
|||||||
#include<string.h>
|
#include<string.h>
|
||||||
#include<stdio.h>
|
#include<stdio.h>
|
||||||
#include<GLFW/glfw3.h>
|
#include<GLFW/glfw3.h>
|
||||||
|
#include"immdraw.h"
|
||||||
|
|
||||||
|
void k3MMeasure(struct k3MObj *this) {
|
||||||
|
for(size_t c = 0; c < this->childCount; c++) {
|
||||||
|
k3MMeasure(this->children[c]);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct k3MEvent newev = {
|
||||||
|
.code = k3M_EVENT_MEASURE,
|
||||||
|
.kind = k3M_EVENTKIND_DIRECT,
|
||||||
|
|
||||||
|
.original = (void*) this,
|
||||||
|
.target = (void*) this,
|
||||||
|
};
|
||||||
|
if(!k3MEventSend(&newev)) {
|
||||||
|
this->wDesired = this->w;
|
||||||
|
this->hDesired = this->h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void k3MArrange(struct k3MObj *this) {
|
||||||
|
struct k3MEvent newev = {
|
||||||
|
.code = k3M_EVENT_ARRANGE,
|
||||||
|
.kind = k3M_EVENTKIND_DIRECT,
|
||||||
|
|
||||||
|
.original = (void*) this,
|
||||||
|
.target = (void*) this,
|
||||||
|
};
|
||||||
|
k3MEventSend(&newev);
|
||||||
|
|
||||||
|
for(size_t c = 0; c < this->childCount; c++) {
|
||||||
|
k3MArrange(this->children[c]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool linear_measure(struct k3MEvent *ev, uint8_t *ud) {
|
||||||
|
struct k3MObj *o = ev->target;
|
||||||
|
|
||||||
|
o->wDesired = 0;
|
||||||
|
o->hDesired = 0;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < o->childCount; i++) {
|
||||||
|
struct k3MObj *c = o->children[i];
|
||||||
|
|
||||||
|
if(o->wDesired < c->wDesired) {
|
||||||
|
o->wDesired = c->wDesired;
|
||||||
|
}
|
||||||
|
|
||||||
|
o->hDesired += c->hDesired;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static bool linear_arrange(struct k3MEvent *ev, uint8_t *ud) {
|
||||||
|
struct k3MObj *o = ev->target;
|
||||||
|
|
||||||
|
size_t y = o->y;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < o->childCount; i++) {
|
||||||
|
struct k3MObj *c = o->children[i];
|
||||||
|
|
||||||
|
c->x = o->x;
|
||||||
|
c->y = y;
|
||||||
|
|
||||||
|
c->w = c->wDesired;
|
||||||
|
c->h = c->hDesired;
|
||||||
|
|
||||||
|
y += c->h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void k3MSetLayoutLinear(struct k3MObj *this, bool vertical) {
|
||||||
|
k3MRegisterEventHandler(this, k3M_EVENT_MEASURE, linear_measure, NULL, 0);
|
||||||
|
k3MRegisterEventHandler(this, k3M_EVENT_ARRANGE, linear_arrange, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h) {
|
void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h) {
|
||||||
this->x = x;
|
this->x = x;
|
||||||
@ -38,6 +110,8 @@ int k3MRegisterEventHandler_(struct k3MObj *obj, uint16_t evcode, k3MEventHandle
|
|||||||
if(ud) {
|
if(ud) {
|
||||||
memcpy(obj->handlers[obj->handlerCount - 1].ud, ud, udSize);
|
memcpy(obj->handlers[obj->handlerCount - 1].ud, ud, udSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool k3MEventSend(struct k3MEvent *ev) {
|
bool k3MEventSend(struct k3MEvent *ev) {
|
||||||
@ -83,10 +157,9 @@ static void obj_draw(struct k3MObj *this) {
|
|||||||
bgColor[3] = bgColorProp->si[3] / 255.0;
|
bgColor[3] = bgColorProp->si[3] / 255.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
k3BatchAdd(NULL, (struct k3RectF) {0, 0, 1, 1}, (struct k3RectF) {
|
if(bgColor[3] != 0) {
|
||||||
this->x, this->y,
|
immdraw_fill_rect(this->x, this->y, this->w, this->h, bgColor[0], bgColor[1], bgColor[2], bgColor[3], borderRadius);
|
||||||
this->w, this->h
|
}
|
||||||
}, 0, bgColor, borderRadius);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool label_draw(struct k3MEvent *ev, uint8_t *ud) {
|
static bool label_draw(struct k3MEvent *ev, uint8_t *ud) {
|
||||||
@ -95,7 +168,13 @@ static bool label_draw(struct k3MEvent *ev, uint8_t *ud) {
|
|||||||
obj_draw((void*) this);
|
obj_draw((void*) this);
|
||||||
|
|
||||||
if(this->txt) {
|
if(this->txt) {
|
||||||
k3FontDraw(this->font, this->x, this->y, this->sz, this->txt, (vec4) {1, 1, 1, 1});
|
int alignment = k3M_ALIGN_CENTER;
|
||||||
|
|
||||||
|
struct k3MProperty *prop = k3MFindProperty(this, k3M_PROP_HORIZONTAL_ALIGNMENT, false);
|
||||||
|
if(prop) alignment = prop->si[0];
|
||||||
|
|
||||||
|
immdraw_font_draw(this->font, this->x, this->y, this->w, this->sz, strlen(this->txt), this->txt, alignment,
|
||||||
|
1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -105,7 +184,7 @@ struct k3MLabel *k3MLabel(struct k3Font *font, float sz, const char *txt) {
|
|||||||
struct k3MLabel *ret = calloc(1, sizeof(*ret));
|
struct k3MLabel *ret = calloc(1, sizeof(*ret));
|
||||||
ret->font = font;
|
ret->font = font;
|
||||||
ret->sz = sz;
|
ret->sz = sz;
|
||||||
ret->txt = txt;
|
ret->txt = strdup(txt);
|
||||||
|
|
||||||
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, label_draw, NULL, 0);
|
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, label_draw, NULL, 0);
|
||||||
|
|
||||||
@ -260,11 +339,19 @@ static bool textbutton_draw(struct k3MEvent *ev, uint8_t *ud) {
|
|||||||
obj_draw((void*) this);
|
obj_draw((void*) this);
|
||||||
|
|
||||||
if(this->txt) {
|
if(this->txt) {
|
||||||
struct k3RectF txtsz;
|
/*struct k3RectF txtsz;
|
||||||
k3FontSz(this->font, this->sz, this->txt, &txtsz);
|
k3FontSz(this->font, this->sz, this->txt, &txtsz);
|
||||||
|
|
||||||
k3FontDraw(this->font, this->x + this->w / 2 - txtsz.w / 2, this->y, this->sz, this->txt, (vec4) {
|
k3FontDraw(this->font, this->x + this->w / 2 - txtsz.w / 2, this->y, this->sz, this->txt, (vec4) {
|
||||||
1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1});
|
1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1});*/
|
||||||
|
|
||||||
|
int alignment = k3M_ALIGN_CENTER;
|
||||||
|
|
||||||
|
struct k3MProperty *prop = k3MFindProperty(this, k3M_PROP_HORIZONTAL_ALIGNMENT, false);
|
||||||
|
if(prop) alignment = prop->si[0];
|
||||||
|
|
||||||
|
immdraw_font_draw(this->font, this->x, this->y, this->w, this->sz, strlen(this->txt), this->txt, alignment,
|
||||||
|
1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1 - 0.8 * this->disabled, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -274,7 +361,7 @@ struct k3MTextButton *k3MTextButton(struct k3Font *font, float sz, const char *t
|
|||||||
|
|
||||||
ret->font = font;
|
ret->font = font;
|
||||||
ret->sz = sz;
|
ret->sz = sz;
|
||||||
ret->txt = txt;
|
ret->txt = strdup(txt);
|
||||||
|
|
||||||
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textbutton_draw, NULL, 0);
|
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textbutton_draw, NULL, 0);
|
||||||
|
|
||||||
@ -287,13 +374,16 @@ static bool textinput_draw(struct k3MEvent *ev, uint8_t *ud) {
|
|||||||
obj_draw((void*) this);
|
obj_draw((void*) this);
|
||||||
|
|
||||||
if(this->txt) {
|
if(this->txt) {
|
||||||
int isPlaceholder = strlen(this->txt) == 0;
|
bool isPlaceholder = strlen(this->txt) == 0;
|
||||||
const char *txt = isPlaceholder ? this->placeholder : this->txt;
|
const char *txt = isPlaceholder ? this->placeholder : this->txt;
|
||||||
|
|
||||||
struct k3RectF txtsz;
|
/*struct k3RectF txtsz;
|
||||||
k3FontSz(this->font, this->sz, txt, &txtsz);
|
k3FontSz(this->font, this->sz, txt, &txtsz);
|
||||||
|
|
||||||
k3FontDraw(this->font, this->x, this->y, this->sz, txt, (vec4) {1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1});
|
k3FontDraw(this->font, this->x, this->y, this->sz, txt, (vec4) {1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1});*/
|
||||||
|
|
||||||
|
immdraw_font_draw(this->font, this->x, this->y, this->w, this->sz, strlen(txt), txt, k3M_ALIGN_LEFT,
|
||||||
|
1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1 - 0.5 * isPlaceholder, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -302,7 +392,7 @@ static bool textinput_key(struct k3MEvent *ev, uint8_t *ud) {
|
|||||||
struct k3MTextInput *this = (void*) ev->target;
|
struct k3MTextInput *this = (void*) ev->target;
|
||||||
|
|
||||||
if(ev->key.num == GLFW_KEY_BACKSPACE && ev->code != k3M_EVENT_KEY_RELEASE) {
|
if(ev->key.num == GLFW_KEY_BACKSPACE && ev->code != k3M_EVENT_KEY_RELEASE) {
|
||||||
char *last = k3UTF8LastCodepointZ(this->txt);
|
char *last = (char*) k3UTF8LastCodepointZ(this->txt);
|
||||||
if(last) {
|
if(last) {
|
||||||
*last = 0;
|
*last = 0;
|
||||||
}
|
}
|
||||||
@ -336,7 +426,7 @@ struct k3MTextInput *k3MTextInput(struct k3Font *font, float sz, const char *pla
|
|||||||
|
|
||||||
ret->font = font;
|
ret->font = font;
|
||||||
ret->sz = sz;
|
ret->sz = sz;
|
||||||
ret->placeholder = placeholder ? placeholder : "";
|
ret->placeholder = strdup(placeholder ? placeholder : "");
|
||||||
ret->txt = strdup(txt ? txt : "");
|
ret->txt = strdup(txt ? txt : "");
|
||||||
|
|
||||||
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textinput_draw, NULL, 0);
|
k3MRegisterEventHandler(ret, k3M_EVENT_DRAW, textinput_draw, NULL, 0);
|
||||||
|
32
src/k3menu.h
32
src/k3menu.h
@ -3,8 +3,9 @@
|
|||||||
#include<stdint.h>
|
#include<stdint.h>
|
||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
#include<stdbool.h>
|
#include<stdbool.h>
|
||||||
#include"k3font.h"
|
#include<stddef.h>
|
||||||
|
|
||||||
|
struct k3Font;
|
||||||
struct k3MObj;
|
struct k3MObj;
|
||||||
|
|
||||||
#define k3M_EVENT_MOUSE_ENTER 0
|
#define k3M_EVENT_MOUSE_ENTER 0
|
||||||
@ -18,7 +19,9 @@ struct k3MObj;
|
|||||||
#define k3M_EVENT_INPUT 8
|
#define k3M_EVENT_INPUT 8
|
||||||
#define k3M_EVENT_DRAW 9
|
#define k3M_EVENT_DRAW 9
|
||||||
#define k3M_EVENT_COMPLETE 10
|
#define k3M_EVENT_COMPLETE 10
|
||||||
#define k3M_EVENT_ALL 11
|
#define k3M_EVENT_MEASURE 11
|
||||||
|
#define k3M_EVENT_ARRANGE 12
|
||||||
|
#define k3M_EVENT_ALL 13
|
||||||
|
|
||||||
#define k3M_MOUSE_BUTTON_0 0
|
#define k3M_MOUSE_BUTTON_0 0
|
||||||
#define k3M_MOUSE_BUTTON_1 1
|
#define k3M_MOUSE_BUTTON_1 1
|
||||||
@ -30,6 +33,16 @@ struct k3MObj;
|
|||||||
|
|
||||||
#define k3M_USERDATA_SIZE 16
|
#define k3M_USERDATA_SIZE 16
|
||||||
|
|
||||||
|
#define k3M_ALIGN_LEFT 0
|
||||||
|
#define k3M_ALIGN_CENTER 1
|
||||||
|
#define k3M_ALIGN_RIGHT 2
|
||||||
|
|
||||||
|
#ifdef k3M_FIXED_POINT
|
||||||
|
typedef uint8_t k3MCC;
|
||||||
|
#else
|
||||||
|
typedef float k3MCC;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct k3MEvent {
|
struct k3MEvent {
|
||||||
uint16_t code;
|
uint16_t code;
|
||||||
|
|
||||||
@ -64,6 +77,8 @@ typedef struct k3MEventHandler {
|
|||||||
enum k3MPropertyType {
|
enum k3MPropertyType {
|
||||||
k3M_PROP_BG_COLOR,
|
k3M_PROP_BG_COLOR,
|
||||||
k3M_PROP_BORDER_RADIUS,
|
k3M_PROP_BORDER_RADIUS,
|
||||||
|
k3M_PROP_MARGIN,
|
||||||
|
k3M_PROP_HORIZONTAL_ALIGNMENT,
|
||||||
};
|
};
|
||||||
struct k3MProperty {
|
struct k3MProperty {
|
||||||
enum k3MPropertyType type;
|
enum k3MPropertyType type;
|
||||||
@ -85,6 +100,9 @@ struct k3MObj {
|
|||||||
int16_t w;
|
int16_t w;
|
||||||
int16_t h;
|
int16_t h;
|
||||||
|
|
||||||
|
int16_t wDesired;
|
||||||
|
int16_t hDesired;
|
||||||
|
|
||||||
bool invisible, hovered, disabled;
|
bool invisible, hovered, disabled;
|
||||||
|
|
||||||
k3MEventHandler *handlers;
|
k3MEventHandler *handlers;
|
||||||
@ -93,6 +111,16 @@ struct k3MObj {
|
|||||||
struct k3MProperty *properties;
|
struct k3MProperty *properties;
|
||||||
size_t propertyCount;
|
size_t propertyCount;
|
||||||
};
|
};
|
||||||
|
struct k3MObj *k3MObj();
|
||||||
|
|
||||||
|
/* Akin to the measure pass of WPF. Recursive, called by parent. Sets wDesired and hDesired. */
|
||||||
|
void k3MMeasure(struct k3MObj *this);
|
||||||
|
|
||||||
|
/* Akin to the arrange pass of WPF. Recursive, called by parent after w and h is set. Adjusts all children using it's own definitive size. */
|
||||||
|
void k3MArrange(struct k3MObj *this);
|
||||||
|
|
||||||
|
/* Set linear layout management on this object. Must not be called on descendants of k3MObj. */
|
||||||
|
void k3MSetLayoutLinear(struct k3MObj *this, bool vertical);
|
||||||
|
|
||||||
#define k3MenuSetBounds(a, x, y, w, h) k3MenuSetBounds_((struct k3MObj*) (a), (x), (y), (w), (h))
|
#define k3MenuSetBounds(a, x, y, w, h) k3MenuSetBounds_((struct k3MObj*) (a), (x), (y), (w), (h))
|
||||||
void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h);
|
void k3MenuSetBounds_(struct k3MObj *this, int16_t x, int16_t y, int16_t w, int16_t h);
|
||||||
|
Loading…
Reference in New Issue
Block a user