Compare commits

...

2 Commits

Author SHA1 Message Date
En Yi 9106899c8a Remove unused components 2023-02-11 22:12:17 +08:00
En Yi 9d959bad07 Add simple button for menu testing
Changelog:
- Incorporate raygui
    - raygui works but I would prefer to separate out detection logic
      and rendering. So, adapt the original code for this
- ECS is not suitable for raygui (at least at this scale)
    - It is more trouble than it is worth
- Implement simple menu test scene with two buttons
    - They do nothing
2023-02-11 20:51:01 +08:00
8 changed files with 5086 additions and 24 deletions

View File

@ -5,6 +5,7 @@ add_library(lib_scenes STATIC
menu_impl.c menu_impl.c
game_systems.c game_systems.c
AABB.c AABB.c
gui.c
) )
target_include_directories(lib_scenes target_include_directories(lib_scenes
PUBLIC PUBLIC

View File

@ -4,7 +4,7 @@
#include <stdint.h> #include <stdint.h>
// TODO: Look at sc to use macros to auto generate functions // TODO: Look at sc to use macros to auto generate functions
#define N_COMPONENTS 9 #define N_COMPONENTS 7
enum ComponentEnum enum ComponentEnum
{ {
CBBOX_COMP_T, CBBOX_COMP_T,
@ -14,8 +14,6 @@ enum ComponentEnum
CJUMP_COMP_T, CJUMP_COMP_T,
CPLAYERSTATE_T, CPLAYERSTATE_T,
CCONTAINER_T, CCONTAINER_T,
CSELECTABLE_T,
CSELECTION_T,
}; };
typedef enum ComponentEnum ComponentEnum_t; typedef enum ComponentEnum ComponentEnum_t;
@ -97,22 +95,6 @@ typedef struct _CContainer_t
ContainerItem_t item; ContainerItem_t item;
}CContainer_t; }CContainer_t;
typedef struct _CSelection_t
{
uint8_t max_choices;
uint8_t curr_choice;
void * data_arr;
unsigned int elem_size;
}CSelection_t;
typedef struct _CSelectable_t CSelectable_t;
typedef void(*selected_callback_t)(CSelectable_t *);
struct _CSelectable_t
{
selected_callback_t callback;
};
static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y) static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y)
{ {
p_bbox->size.x = x; p_bbox->size.x = x;

View File

@ -11,8 +11,6 @@ static CMovementState_t cmstate_buffer[MAX_COMP_POOL_SIZE];
static CJump_t cjump_buffer[1]; // Only player is expected to have this static CJump_t cjump_buffer[1]; // Only player is expected to have this
static CPlayerState_t cplayerstate_buffer[1]; // Only player is expected to have this static CPlayerState_t cplayerstate_buffer[1]; // Only player is expected to have this
static CContainer_t ccontainer_buffer[MAX_COMP_POOL_SIZE]; static CContainer_t ccontainer_buffer[MAX_COMP_POOL_SIZE];
static CSelectable_t cselectable_buffer[32];
static CSelection_t cselection_buffer[32];
// Use hashmap as a Set // Use hashmap as a Set
// Use list will be used to check if an object exist // Use list will be used to check if an object exist
@ -39,8 +37,6 @@ static MemPool_t comp_mempools[N_COMPONENTS] =
{cjump_buffer, 1, sizeof(CJump_t), NULL, {0}}, {cjump_buffer, 1, sizeof(CJump_t), NULL, {0}},
{cplayerstate_buffer, 1, sizeof(CPlayerState_t), NULL, {0}}, {cplayerstate_buffer, 1, sizeof(CPlayerState_t), NULL, {0}},
{ccontainer_buffer, MAX_COMP_POOL_SIZE, sizeof(CContainer_t), NULL, {0}}, {ccontainer_buffer, MAX_COMP_POOL_SIZE, sizeof(CContainer_t), NULL, {0}},
{cselectable_buffer, 32, sizeof(CSelectable_t), NULL, {0}},
{cselection_buffer, 32, sizeof(CSelection_t), NULL, {0}},
}; };
static MemPool_t ent_mempool = {entity_buffer, MAX_COMP_POOL_SIZE, sizeof(Entity_t), NULL, {0}}; static MemPool_t ent_mempool = {entity_buffer, MAX_COMP_POOL_SIZE, sizeof(Entity_t), NULL, {0}};

375
engine/gui.c 100644
View File

@ -0,0 +1,375 @@
#include "gui.h"
#include <string.h>
#define RAYGUI_MAX_CONTROLS 16 // Maximum number of standard controls
#define RAYGUI_MAX_PROPS_BASE 16 // Maximum number of standard properties
#define RAYGUI_MAX_PROPS_EXTENDED 8 // Maximum number of extended properties
#define MAX_LINE_BUFFER_SIZE 256
static unsigned int guiStyle[RAYGUI_MAX_CONTROLS*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED)] = { 0 };
static bool guiStyleLoaded = false; // Style loaded flag for lazy style initialization
static Font guiFont = { 0 }; // Gui current font (WARNING: highly coupled to raylib)
typedef enum { BORDER = 0, BASE, TEXT, OTHER } GuiPropertyElement;
void GuiLoadStyleDefault(void)
{
// We set this variable first to avoid cyclic function calls
// when calling GuiSetStyle() and GuiGetStyle()
guiStyleLoaded = true;
// Initialize default LIGHT style property values
GuiSetStyle(DEFAULT, BORDER_COLOR_NORMAL, 0x838383ff);
GuiSetStyle(DEFAULT, BASE_COLOR_NORMAL, 0xc9c9c9ff);
GuiSetStyle(DEFAULT, TEXT_COLOR_NORMAL, 0x686868ff);
GuiSetStyle(DEFAULT, BORDER_COLOR_FOCUSED, 0x5bb2d9ff);
GuiSetStyle(DEFAULT, BASE_COLOR_FOCUSED, 0xc9effeff);
GuiSetStyle(DEFAULT, TEXT_COLOR_FOCUSED, 0x6c9bbcff);
GuiSetStyle(DEFAULT, BORDER_COLOR_PRESSED, 0x0492c7ff);
GuiSetStyle(DEFAULT, BASE_COLOR_PRESSED, 0x97e8ffff);
GuiSetStyle(DEFAULT, TEXT_COLOR_PRESSED, 0x368bafff);
GuiSetStyle(DEFAULT, BORDER_COLOR_DISABLED, 0xb5c1c2ff);
GuiSetStyle(DEFAULT, BASE_COLOR_DISABLED, 0xe6e9e9ff);
GuiSetStyle(DEFAULT, TEXT_COLOR_DISABLED, 0xaeb7b8ff);
GuiSetStyle(DEFAULT, BORDER_WIDTH, 1); // WARNING: Some controls use other values
GuiSetStyle(DEFAULT, TEXT_PADDING, 0); // WARNING: Some controls use other values
GuiSetStyle(DEFAULT, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER); // WARNING: Some controls use other values
// Initialize control-specific property values
// NOTE: Those properties are in default list but require specific values by control type
GuiSetStyle(LABEL, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
GuiSetStyle(BUTTON, BORDER_WIDTH, 2);
GuiSetStyle(SLIDER, TEXT_PADDING, 4);
GuiSetStyle(CHECKBOX, TEXT_PADDING, 4);
GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_RIGHT);
GuiSetStyle(TEXTBOX, TEXT_PADDING, 4);
GuiSetStyle(TEXTBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
GuiSetStyle(VALUEBOX, TEXT_PADDING, 0);
GuiSetStyle(VALUEBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
GuiSetStyle(SPINNER, TEXT_PADDING, 0);
GuiSetStyle(SPINNER, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
GuiSetStyle(STATUSBAR, TEXT_PADDING, 8);
GuiSetStyle(STATUSBAR, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT);
// Initialize extended property values
// NOTE: By default, extended property values are initialized to 0
GuiSetStyle(DEFAULT, TEXT_SIZE, 10); // DEFAULT, shared by all controls
GuiSetStyle(DEFAULT, TEXT_SPACING, 1); // DEFAULT, shared by all controls
GuiSetStyle(DEFAULT, LINE_COLOR, 0x90abb5ff); // DEFAULT specific property
GuiSetStyle(DEFAULT, BACKGROUND_COLOR, 0xf5f5f5ff); // DEFAULT specific property
GuiSetStyle(TOGGLE, GROUP_PADDING, 2);
GuiSetStyle(SLIDER, SLIDER_WIDTH, 16);
GuiSetStyle(SLIDER, SLIDER_PADDING, 1);
GuiSetStyle(PROGRESSBAR, PROGRESS_PADDING, 1);
GuiSetStyle(CHECKBOX, CHECK_PADDING, 1);
GuiSetStyle(COMBOBOX, COMBO_BUTTON_WIDTH, 32);
GuiSetStyle(COMBOBOX, COMBO_BUTTON_SPACING, 2);
GuiSetStyle(DROPDOWNBOX, ARROW_PADDING, 16);
GuiSetStyle(DROPDOWNBOX, DROPDOWN_ITEMS_SPACING, 2);
GuiSetStyle(TEXTBOX, TEXT_LINES_SPACING, 4);
GuiSetStyle(TEXTBOX, TEXT_INNER_PADDING, 4);
GuiSetStyle(SPINNER, SPIN_BUTTON_WIDTH, 24);
GuiSetStyle(SPINNER, SPIN_BUTTON_SPACING, 2);
GuiSetStyle(SCROLLBAR, BORDER_WIDTH, 0);
GuiSetStyle(SCROLLBAR, ARROWS_VISIBLE, 0);
GuiSetStyle(SCROLLBAR, ARROWS_SIZE, 6);
GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_PADDING, 0);
GuiSetStyle(SCROLLBAR, SCROLL_SLIDER_SIZE, 16);
GuiSetStyle(SCROLLBAR, SCROLL_PADDING, 0);
GuiSetStyle(SCROLLBAR, SCROLL_SPEED, 12);
GuiSetStyle(LISTVIEW, LIST_ITEMS_HEIGHT, 28);
GuiSetStyle(LISTVIEW, LIST_ITEMS_SPACING, 2);
GuiSetStyle(LISTVIEW, SCROLLBAR_WIDTH, 12);
GuiSetStyle(LISTVIEW, SCROLLBAR_SIDE, SCROLLBAR_RIGHT_SIDE);
GuiSetStyle(COLORPICKER, COLOR_SELECTOR_SIZE, 8);
GuiSetStyle(COLORPICKER, HUEBAR_WIDTH, 16);
GuiSetStyle(COLORPICKER, HUEBAR_PADDING, 8);
GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_HEIGHT, 8);
GuiSetStyle(COLORPICKER, HUEBAR_SELECTOR_OVERFLOW, 2);
if (guiFont.texture.id != GetFontDefault().texture.id)
{
// Unload previous font texture
UnloadTexture(guiFont.texture);
// Setup default raylib font
guiFont = GetFontDefault();
// Setup default raylib font rectangle
Rectangle whiteChar = { 41, 46, 2, 8 };
SetShapesTexture(guiFont.texture, whiteChar);
}
}
void GuiSetStyle(int control, int property, int value)
{
if (!guiStyleLoaded) GuiLoadStyleDefault();
guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
// Default properties are propagated to all controls
if ((control == 0) && (property < RAYGUI_MAX_PROPS_BASE))
{
for (int i = 1; i < RAYGUI_MAX_CONTROLS; i++) guiStyle[i*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property] = value;
}
}
int GuiGetStyle(int control, int property)
{
if (!guiStyleLoaded) GuiLoadStyleDefault();
return guiStyle[control*(RAYGUI_MAX_PROPS_BASE + RAYGUI_MAX_PROPS_EXTENDED) + property];
}
static int GetTextWidth(const char *text)
{
#if !defined(ICON_TEXT_PADDING)
#define ICON_TEXT_PADDING 4
#endif
Vector2 textSize = { 0 };
int textIconOffset = 0;
if ((text != NULL) && (text[0] != '\0'))
{
if (text[0] == '#')
{
for (int i = 1; (text[i] != '\0') && (i < 5); i++)
{
if (text[i] == '#')
{
textIconOffset = i;
break;
}
}
}
text += textIconOffset;
// Make sure guiFont is set, GuiGetStyle() initializes it lazynessly
float fontSize = (float)GuiGetStyle(DEFAULT, TEXT_SIZE);
// Custom MeasureText() implementation
if ((guiFont.texture.id > 0) && (text != NULL))
{
// Get size in bytes of text, considering end of line and line break
int size = 0;
for (int i = 0; i < MAX_LINE_BUFFER_SIZE; i++)
{
if ((text[i] != '\0') && (text[i] != '\n')) size++;
else break;
}
float scaleFactor = fontSize/(float)guiFont.baseSize;
textSize.y = (float)guiFont.baseSize*scaleFactor;
float glyphWidth = 0.0f;
for (int i = 0, codepointSize = 0; i < size; i += codepointSize)
{
int codepoint = GetCodepointNext(&text[i], &codepointSize);
int codepointIndex = GetGlyphIndex(guiFont, codepoint);
if (guiFont.glyphs[codepointIndex].advanceX == 0) glyphWidth = ((float)guiFont.recs[codepointIndex].width*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
else glyphWidth = ((float)guiFont.glyphs[codepointIndex].advanceX*scaleFactor + GuiGetStyle(DEFAULT, TEXT_SPACING));
textSize.x += glyphWidth;
}
}
}
return (int)textSize.x;
}
const char **GetTextLines(const char *text, int *count)
{
#define RAYGUI_MAX_TEXT_LINES 128
static const char *lines[RAYGUI_MAX_TEXT_LINES] = { 0 };
for (int i = 0; i < RAYGUI_MAX_TEXT_LINES; i++) lines[i] = NULL; // Init NULL pointers to substrings
int textSize = (int)strlen(text);
lines[0] = text;
int len = 0;
*count = 1;
int lineSize = 0; // Stores current line size, not returned
for (int i = 0, k = 0; (i < textSize) && (*count < RAYGUI_MAX_TEXT_LINES); i++)
{
if (text[i] == '\n')
{
lineSize = len;
k++;
lines[k] = &text[i + 1]; // WARNING: next value is valid?
len = 0;
*count += 1;
}
else len++;
}
//lines[*count - 1].size = len;
return lines;
}
static void GuiDrawRectangle(Rectangle rec, int borderWidth, Color borderColor, Color color)
{
if (color.a > 0)
{
// Draw rectangle filled with color
DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, (int)rec.height, color);
}
if (borderWidth > 0)
{
// Draw rectangle border lines with color
DrawRectangle((int)rec.x, (int)rec.y, (int)rec.width, borderWidth, borderColor);
DrawRectangle((int)rec.x, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, borderColor);
DrawRectangle((int)rec.x + (int)rec.width - borderWidth, (int)rec.y + borderWidth, borderWidth, (int)rec.height - 2*borderWidth, borderColor);
DrawRectangle((int)rec.x, (int)rec.y + (int)rec.height - borderWidth, (int)rec.width, borderWidth, borderColor);
}
}
static void GuiDrawText(const char *text, Rectangle bounds, int alignment, Color tint)
{
#define TEXT_VALIGN_PIXEL_OFFSET(h) ((int)h%2) // Vertical alignment for pixel perfect
#if !defined(ICON_TEXT_PADDING)
#define ICON_TEXT_PADDING 4
#endif
// We process the text lines one by one
if ((text != NULL) && (text[0] != '\0'))
{
// Get text lines ('\n' delimiter) to process lines individually
// NOTE: We can't use GuiTextSplit() because it can be already use before calling
// GuiDrawText() and static buffer would be overriden :(
int lineCount = 0;
const char **lines = GetTextLines(text, &lineCount);
//Rectangle textBounds = GetTextBounds(LABEL, bounds);
float totalHeight = (float)(lineCount*GuiGetStyle(DEFAULT, TEXT_SIZE) + (lineCount - 1)*GuiGetStyle(DEFAULT, TEXT_SIZE)/2);
float posOffsetY = 0;
for (int i = 0; i < lineCount; i++)
{
// Get text position depending on alignment and iconId
//---------------------------------------------------------------------------------
Vector2 position = { bounds.x, bounds.y };
// TODO: We get text size after icon has been processed
// WARNING: GetTextWidth() also processes text icon to get width! -> Really needed?
int textSizeX = GetTextWidth(lines[i]);
// Check guiTextAlign global variables
switch (alignment)
{
case TEXT_ALIGN_LEFT:
{
position.x = bounds.x;
position.y = bounds.y + posOffsetY + bounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height);
} break;
case TEXT_ALIGN_CENTER:
{
position.x = bounds.x + bounds.width/2 - textSizeX/2;
position.y = bounds.y + posOffsetY + bounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height);
} break;
case TEXT_ALIGN_RIGHT:
{
position.x = bounds.x + bounds.width - textSizeX;
position.y = bounds.y + posOffsetY + bounds.height/2 - totalHeight/2 + TEXT_VALIGN_PIXEL_OFFSET(bounds.height);
} break;
default: break;
}
// NOTE: Make sure we get pixel-perfect coordinates,
// In case of decimals we got weird text positioning
position.x = (float)((int)position.x);
position.y = (float)((int)position.y);
//---------------------------------------------------------------------------------
// Draw text (with icon if available)
//---------------------------------------------------------------------------------
//DrawTextEx(guiFont, text, position, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), (float)GuiGetStyle(DEFAULT, TEXT_SPACING), tint);
// Get size in bytes of text,
// considering end of line and line break
int size = 0;
for (int c = 0; (lines[i][c] != '\0') && (lines[i][c] != '\n'); c++, size++){ }
float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/guiFont.baseSize;
int textOffsetY = 0;
float textOffsetX = 0.0f;
for (int c = 0, codepointSize = 0; c < size; c += codepointSize)
{
int codepoint = GetCodepointNext(&lines[i][c], &codepointSize);
int index = GetGlyphIndex(guiFont, codepoint);
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
if (codepoint == 0x3f) codepointSize = 1;
if (codepoint == '\n') break; // WARNING: Lines are already processed manually, no need to keep drawing after this codepoint
else
{
if ((codepoint != ' ') && (codepoint != '\t'))
{
// TODO: Draw only required text glyphs fitting the bounds.width, '...' can be appended at the end of the text
if (textOffsetX < bounds.width)
{
DrawTextCodepoint(guiFont, codepoint, (Vector2){ position.x + textOffsetX, position.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), tint);
}
}
if (guiFont.glyphs[index].advanceX == 0) textOffsetX += ((float)guiFont.recs[index].width*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
else textOffsetX += ((float)guiFont.glyphs[index].advanceX*scaleFactor + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
}
}
posOffsetY += (float)GuiGetStyle(DEFAULT, TEXT_SIZE)*1.5f; // TODO: GuiGetStyle(DEFAULT, TEXT_LINE_SPACING)?
//---------------------------------------------------------------------------------
}
}
}
static Rectangle GetTextBounds(int control, Rectangle bounds)
{
Rectangle textBounds = bounds;
textBounds.x = bounds.x + GuiGetStyle(control, BORDER_WIDTH);
textBounds.y = bounds.y + GuiGetStyle(control, BORDER_WIDTH);
textBounds.width = bounds.width - 2*GuiGetStyle(control, BORDER_WIDTH) - 2*GuiGetStyle(control, TEXT_PADDING);
textBounds.height = bounds.height - 2*GuiGetStyle(control, BORDER_WIDTH);
// Consider TEXT_PADDING properly, depends on control type and TEXT_ALIGNMENT
switch (control)
{
case COMBOBOX: textBounds.width -= (GuiGetStyle(control, COMBO_BUTTON_WIDTH) + GuiGetStyle(control, COMBO_BUTTON_SPACING)); break;
//case VALUEBOX: break; // NOTE: ValueBox text value always centered, text padding applies to label
default:
{
if (GuiGetStyle(control, TEXT_ALIGNMENT) == TEXT_ALIGN_RIGHT) textBounds.x -= GuiGetStyle(control, TEXT_PADDING);
else textBounds.x += GuiGetStyle(control, TEXT_PADDING);
textBounds.width -= 2 * GuiGetStyle(control, TEXT_PADDING);
}
break;
}
// TODO: Special cases (no label): COMBOBOX, DROPDOWNBOX, LISTVIEW (scrollbar?)
// More special cases (label on side): CHECKBOX, SLIDER, VALUEBOX, SPINNER
return textBounds;
}
//------- End of raygui section---------//
void UI_button(const UIComp_t *comp, const char *text)
{
GuiDrawRectangle(comp->bbox, GuiGetStyle(BUTTON, BORDER_WIDTH), Fade(GetColor(GuiGetStyle(BUTTON, BORDER + (comp->state*3))), comp->alpha), Fade(GetColor(GuiGetStyle(BUTTON, BASE + (comp->state*3))), comp->alpha));
GuiDrawText(text, GetTextBounds(BUTTON, comp->bbox), GuiGetStyle(BUTTON, TEXT_ALIGNMENT), Fade(GetColor(GuiGetStyle(BUTTON, TEXT + (comp->state*3))), comp->alpha));
}
void init_UI(void)
{
GuiLoadStyleDefault();
}

16
engine/gui.h 100644
View File

@ -0,0 +1,16 @@
#ifndef __GUI_H
#define __GUI_H
#include "raylib.h"
#include "raygui.h"
typedef struct UIComp
{
Rectangle bbox;
GuiState state;
float alpha;
bool pressed;
}UIComp_t;
void init_UI(void);
void UI_button(const UIComp_t *bbox, const char *text);
#endif

View File

@ -1,18 +1,62 @@
#include "menu_impl.h" #include "menu_impl.h"
#include "gui.h"
static UIComp_t buttons[2] =
{
{
.bbox = {25,255,125,30},
.state = STATE_NORMAL,
.alpha = 1.0
},
{
.bbox = {25,300,125,30},
.state = STATE_NORMAL,
.alpha = 1.0
}
};
static void menu_scene_render_func(Scene_t *scene) static void menu_scene_render_func(Scene_t *scene)
{ {
DrawText("This is a game", 25, 220, 12, BLACK);
UI_button(buttons, "Start");
UI_button(buttons + 1, "Exit");
} }
static void menu_do_action(Scene_t *scene, ActionType_t action, bool pressed) static void menu_do_action(Scene_t *scene, ActionType_t action, bool pressed)
{ {
} }
static void gui_loop(Scene_t* scene)
{
for (size_t i=0;i<2;i++)
{
if ((buttons[i].state != STATE_DISABLED))
{
Vector2 mousePoint = GetMousePosition();
// Check button state
if (CheckCollisionPointRec(mousePoint, buttons[i].bbox))
{
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) buttons[i].state = STATE_PRESSED;
else buttons[i].state = STATE_FOCUSED;
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) buttons[i].pressed = true;
}
else
{
buttons[i].state = STATE_NORMAL;
}
}
}
}
void init_menu_scene(MenuScene_t *scene) void init_menu_scene(MenuScene_t *scene)
{ {
init_scene(&scene->scene, MENU_SCENE, &menu_scene_render_func, &menu_do_action); init_scene(&scene->scene, MENU_SCENE, &menu_scene_render_func, &menu_do_action);
scene->scene.scene_data = &scene->data; scene->scene.scene_data = &scene->data;
sc_array_add(&scene->scene.systems, &gui_loop);
} }
void free_menu_scene(MenuScene_t *scene) void free_menu_scene(MenuScene_t *scene)

View File

@ -4,7 +4,8 @@
typedef struct MenuSceneData typedef struct MenuSceneData
{ {
Entity_t menus[32]; Entity_t *menus[8];
Entity_t *menu_opts[32];
}MenuSceneData_t; }MenuSceneData_t;
typedef struct MenuScene typedef struct MenuScene

4647
engine/raygui.h 100644

File diff suppressed because it is too large Load Diff