From bb455a7ae7c36a63417adfd3850b50801c5a6f87 Mon Sep 17 00:00:00 2001 From: RandyGaul Date: Sun, 7 Jul 2024 15:40:48 -0700 Subject: [PATCH] v1.0 --- docs/api_reference.md | 1 - docs/draw/cf_draw_arc.md | 31 - docs/draw/cf_draw_circle.md | 3 +- docs/draw/cf_draw_circle2.md | 3 +- docs/draw/cf_draw_circle_fill.md | 1 - docs/draw/cf_draw_circle_fill2.md | 1 - docs/ecs/cf_component_begin.md | 10 +- docs/ecs/cf_component_end.md | 12 +- docs/ecs/cf_component_rename.md | 11 +- docs/ecs/cf_component_set_name.md | 12 +- docs/ecs/cf_component_set_optional_cleanup.md | 12 +- .../cf_component_set_optional_initializer.md | 12 +- docs/ecs/cf_component_set_size.md | 12 +- docs/ecs/cf_destroy_entity.md | 8 +- docs/ecs/cf_destroy_entity_delayed.md | 9 +- docs/ecs/cf_destroy_world.md | 13 +- docs/ecs/cf_entity_activate.md | 7 +- docs/ecs/cf_entity_begin.md | 3 +- docs/ecs/cf_entity_change_type.md | 6 +- docs/ecs/cf_entity_deactivate.md | 7 +- docs/ecs/cf_entity_delayed_activate.md | 11 +- docs/ecs/cf_entity_delayed_change_type.md | 12 +- docs/ecs/cf_entity_delayed_deactivate.md | 12 +- docs/ecs/cf_entity_equals.md | 10 +- docs/ecs/cf_entity_get_component.md | 8 +- docs/ecs/cf_entity_get_type_string.md | 8 +- docs/ecs/cf_entity_has_component.md | 8 +- docs/ecs/cf_entity_is_active.md | 7 +- docs/ecs/cf_entity_is_type.md | 8 +- docs/ecs/cf_entity_is_valid.md | 8 +- docs/ecs/cf_entity_type_rename.md | 10 +- docs/ecs/cf_get_component_list.md | 9 +- .../cf_get_component_list_for_entity_type.md | 9 +- docs/ecs/cf_get_components.md | 14 +- docs/ecs/cf_get_entities.md | 13 +- docs/ecs/cf_get_entity_list.md | 9 +- docs/ecs/cf_get_system_list.md | 9 +- docs/ecs/cf_is_entity_type_valid.md | 9 +- docs/ecs/cf_make_entity.md | 5 +- docs/ecs/cf_make_world.md | 12 +- docs/ecs/cf_run_systems.md | 14 +- docs/ecs/cf_system_begin.md | 14 +- docs/ecs/cf_system_end.md | 14 +- docs/ecs/cf_system_require_component.md | 13 +- docs/ecs/cf_system_set_name.md | 14 +- .../ecs/cf_system_set_optional_post_update.md | 14 +- docs/ecs/cf_system_set_optional_pre_update.md | 14 +- docs/ecs/cf_system_set_optional_udata.md | 14 +- docs/ecs/cf_system_set_update.md | 14 +- docs/ecs/cf_world_equals.md | 13 +- docs/ecs/cf_world_peek.md | 13 +- docs/ecs/cf_world_pop.md | 13 +- docs/ecs/cf_world_push.md | 13 +- docs/topics/drawing.md | 1 - include/cute_draw.h | 22 +- include/cute_ecs.h | 235 ++++---- include/cute_version.h | 2 +- libraries/cute/cute_aseprite.h | 111 +++- libraries/cute/cute_c2.h | 33 +- libraries/cute/cute_net.h | 77 ++- libraries/cute/cute_path.h | 562 ------------------ libraries/cute/cute_png.h | 225 +++++-- roadmap.md | 10 + src/cute_draw.cpp | 4 - src/cute_handle_table.cpp | 4 +- src/cute_version.cpp | 2 +- todo.txt | 4 - 67 files changed, 772 insertions(+), 1062 deletions(-) delete mode 100644 docs/draw/cf_draw_arc.md delete mode 100644 libraries/cute/cute_path.h create mode 100644 roadmap.md diff --git a/docs/api_reference.md b/docs/api_reference.md index 08b125229..e6e82ad65 100644 --- a/docs/api_reference.md +++ b/docs/api_reference.md @@ -321,7 +321,6 @@ This is a list of all functions in Cute Framework organized by categories. This ## draw ### functions -- [cf_draw_arc](/draw/cf_draw_arc.md) - [cf_draw_arrow](/draw/cf_draw_arrow.md) - [cf_draw_bezier_line](/draw/cf_draw_bezier_line.md) - [cf_draw_bezier_line2](/draw/cf_draw_bezier_line2.md) diff --git a/docs/draw/cf_draw_arc.md b/docs/draw/cf_draw_arc.md deleted file mode 100644 index a14255488..000000000 --- a/docs/draw/cf_draw_arc.md +++ /dev/null @@ -1,31 +0,0 @@ -[//]: # (This file is automatically generated by Cute Framework's docs parser.) -[//]: # (Do not edit this file by hand!) -[//]: # (See: https://github.com/RandyGaul/cute_framework/blob/master/samples/docs_parser.cpp) -[](../header.md ':include') - -# cf_draw_arc - -Category: [draw](/api_reference?id=draw) -GitHub: [cute_draw.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_draw.h) ---- - -Draws an arc of a circle wireframe. - -```cpp -void cf_draw_arc(CF_V2 p, CF_V2 center_of_arc, float range, int iters, float thickness); -``` - -Parameters | Description ---- | --- -p | Center of the arc. -center_of_arc | Radius of the circle. -range | Angle the arc covers. -iters | Number of edges used for the circle. More looks smoother, but renders slower. -thickness | The thickness of each line to draw. - -## Related Pages - -[cf_draw_circle](/draw/cf_draw_circle.md) -[cf_draw_circle2](/draw/cf_draw_circle2.md) -[cf_draw_circle_fill](/draw/cf_draw_circle_fill.md) -[cf_draw_circle_fill2](/draw/cf_draw_circle_fill2.md) diff --git a/docs/draw/cf_draw_circle.md b/docs/draw/cf_draw_circle.md index 7ebc54350..d9a318020 100644 --- a/docs/draw/cf_draw_circle.md +++ b/docs/draw/cf_draw_circle.md @@ -22,7 +22,6 @@ thickness | The thickness of each line to draw. ## Related Pages -[cf_draw_arc](/draw/cf_draw_arc.md) +[cf_draw_circle_fill2](/draw/cf_draw_circle_fill2.md) [cf_draw_circle2](/draw/cf_draw_circle2.md) [cf_draw_circle_fill](/draw/cf_draw_circle_fill.md) -[cf_draw_circle_fill2](/draw/cf_draw_circle_fill2.md) diff --git a/docs/draw/cf_draw_circle2.md b/docs/draw/cf_draw_circle2.md index 312506927..87c4cf558 100644 --- a/docs/draw/cf_draw_circle2.md +++ b/docs/draw/cf_draw_circle2.md @@ -24,6 +24,5 @@ thickness | The thickness of each line to draw. ## Related Pages [cf_draw_circle](/draw/cf_draw_circle.md) -[cf_draw_arc](/draw/cf_draw_arc.md) -[cf_draw_circle_fill](/draw/cf_draw_circle_fill.md) [cf_draw_circle_fill2](/draw/cf_draw_circle_fill2.md) +[cf_draw_circle_fill](/draw/cf_draw_circle_fill.md) diff --git a/docs/draw/cf_draw_circle_fill.md b/docs/draw/cf_draw_circle_fill.md index ec5e4a0c8..7f2256624 100644 --- a/docs/draw/cf_draw_circle_fill.md +++ b/docs/draw/cf_draw_circle_fill.md @@ -23,5 +23,4 @@ circle | The circle. [cf_draw_circle](/draw/cf_draw_circle.md) [cf_draw_circle2](/draw/cf_draw_circle2.md) -[cf_draw_arc](/draw/cf_draw_arc.md) [cf_draw_circle_fill2](/draw/cf_draw_circle_fill2.md) diff --git a/docs/draw/cf_draw_circle_fill2.md b/docs/draw/cf_draw_circle_fill2.md index fa45cf18a..1a0f0dc4d 100644 --- a/docs/draw/cf_draw_circle_fill2.md +++ b/docs/draw/cf_draw_circle_fill2.md @@ -25,4 +25,3 @@ r | Radius of the circle. [cf_draw_circle](/draw/cf_draw_circle.md) [cf_draw_circle2](/draw/cf_draw_circle2.md) [cf_draw_circle_fill](/draw/cf_draw_circle_fill.md) -[cf_draw_arc](/draw/cf_draw_arc.md) diff --git a/docs/ecs/cf_component_begin.md b/docs/ecs/cf_component_begin.md index fca9b8888..112c604c4 100644 --- a/docs/ecs/cf_component_begin.md +++ b/docs/ecs/cf_component_begin.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Beings the defnition of a new component type. ```cpp void cf_component_begin(); @@ -17,8 +17,12 @@ void cf_component_begin(); ## Remarks -TODO +Once [cf_component_end](/ecs/cf_component_end.md) is called you may instantiate components of this type when creating entities. ## Related Pages -TODO +[cf_component_end](/ecs/cf_component_end.md) +[cf_component_set_name](/ecs/cf_component_set_name.md) +[cf_component_set_size](/ecs/cf_component_set_size.md) +[cf_component_set_optional_initializer](/ecs/cf_component_set_optional_initializer.md) +[cf_component_set_optional_cleanup](/ecs/cf_component_set_optional_cleanup.md) diff --git a/docs/ecs/cf_component_end.md b/docs/ecs/cf_component_end.md index 4e4df26b4..a2e26a22b 100644 --- a/docs/ecs/cf_component_end.md +++ b/docs/ecs/cf_component_end.md @@ -9,16 +9,16 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Completes the definition of this new component type. ```cpp void cf_component_end(); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_component_begin](/ecs/cf_component_begin.md) +[cf_component_set_name](/ecs/cf_component_set_name.md) +[cf_component_set_size](/ecs/cf_component_set_size.md) +[cf_component_set_optional_initializer](/ecs/cf_component_set_optional_initializer.md) +[cf_component_set_optional_cleanup](/ecs/cf_component_set_optional_cleanup.md) diff --git a/docs/ecs/cf_component_rename.md b/docs/ecs/cf_component_rename.md index 1b26fc672..6a8f0a5f5 100644 --- a/docs/ecs/cf_component_rename.md +++ b/docs/ecs/cf_component_rename.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Changes the name of this component type. ```cpp void cf_component_rename(const char* component_name, const char* new_component_name); @@ -17,8 +17,13 @@ void cf_component_rename(const char* component_name, const char* new_component_n ## Remarks -TODO +This is useful for implementing certain editors. ## Related Pages -TODO +[cf_component_begin](/ecs/cf_component_begin.md) +[cf_component_set_name](/ecs/cf_component_set_name.md) +[cf_component_set_size](/ecs/cf_component_set_size.md) +[cf_component_set_optional_initializer](/ecs/cf_component_set_optional_initializer.md) +[cf_component_set_optional_cleanup](/ecs/cf_component_set_optional_cleanup.md) +[cf_component_end](/ecs/cf_component_end.md) diff --git a/docs/ecs/cf_component_set_name.md b/docs/ecs/cf_component_set_name.md index a67cfd800..f59a0462c 100644 --- a/docs/ecs/cf_component_set_name.md +++ b/docs/ecs/cf_component_set_name.md @@ -9,16 +9,16 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Defines the name of this new component type. ```cpp void cf_component_set_name(const char* name); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_component_begin](/ecs/cf_component_begin.md) +[cf_component_end](/ecs/cf_component_end.md) +[cf_component_set_size](/ecs/cf_component_set_size.md) +[cf_component_set_optional_initializer](/ecs/cf_component_set_optional_initializer.md) +[cf_component_set_optional_cleanup](/ecs/cf_component_set_optional_cleanup.md) diff --git a/docs/ecs/cf_component_set_optional_cleanup.md b/docs/ecs/cf_component_set_optional_cleanup.md index fd04cdbe1..8862d5273 100644 --- a/docs/ecs/cf_component_set_optional_cleanup.md +++ b/docs/ecs/cf_component_set_optional_cleanup.md @@ -9,16 +9,16 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Sets an optional cleanup callback, called whenever a component of this type is free'd. ```cpp void cf_component_set_optional_cleanup(CF_ComponentFn* cleanup, void* udata); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_component_begin](/ecs/cf_component_begin.md) +[cf_component_set_name](/ecs/cf_component_set_name.md) +[cf_component_set_size](/ecs/cf_component_set_size.md) +[cf_component_set_optional_initializer](/ecs/cf_component_set_optional_initializer.md) +[cf_component_end](/ecs/cf_component_end.md) diff --git a/docs/ecs/cf_component_set_optional_initializer.md b/docs/ecs/cf_component_set_optional_initializer.md index 75a831034..6fb529b92 100644 --- a/docs/ecs/cf_component_set_optional_initializer.md +++ b/docs/ecs/cf_component_set_optional_initializer.md @@ -9,16 +9,16 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Sets an optional initializer callback, called whenever a component of this type is instantiated. ```cpp void cf_component_set_optional_initializer(CF_ComponentFn* initializer, void* udata); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_component_begin](/ecs/cf_component_begin.md) +[cf_component_set_name](/ecs/cf_component_set_name.md) +[cf_component_set_size](/ecs/cf_component_set_size.md) +[cf_component_end](/ecs/cf_component_end.md) +[cf_component_set_optional_cleanup](/ecs/cf_component_set_optional_cleanup.md) diff --git a/docs/ecs/cf_component_set_size.md b/docs/ecs/cf_component_set_size.md index 9cef79275..555d749e6 100644 --- a/docs/ecs/cf_component_set_size.md +++ b/docs/ecs/cf_component_set_size.md @@ -9,16 +9,16 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Sets the size in bytes of this new component type. ```cpp void cf_component_set_size(size_t size); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_component_begin](/ecs/cf_component_begin.md) +[cf_component_set_name](/ecs/cf_component_set_name.md) +[cf_component_end](/ecs/cf_component_end.md) +[cf_component_set_optional_initializer](/ecs/cf_component_set_optional_initializer.md) +[cf_component_set_optional_cleanup](/ecs/cf_component_set_optional_cleanup.md) diff --git a/docs/ecs/cf_destroy_entity.md b/docs/ecs/cf_destroy_entity.md index 3ca7b662e..d407856c8 100644 --- a/docs/ecs/cf_destroy_entity.md +++ b/docs/ecs/cf_destroy_entity.md @@ -15,10 +15,8 @@ Destroys a specific entity right now. void cf_destroy_entity(CF_Entity entity); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_make_entity](/ecs/cf_make_entity.md) +[cf_entity_get_component](/ecs/cf_entity_get_component.md) +[cf_entity_has_component](/ecs/cf_entity_has_component.md) diff --git a/docs/ecs/cf_destroy_entity_delayed.md b/docs/ecs/cf_destroy_entity_delayed.md index f21898aa5..b256eaa12 100644 --- a/docs/ecs/cf_destroy_entity_delayed.md +++ b/docs/ecs/cf_destroy_entity_delayed.md @@ -15,10 +15,9 @@ Marks a specific entity for delayed destruction. void cf_destroy_entity_delayed(CF_Entity entity); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_make_entity](/ecs/cf_make_entity.md) +[cf_destroy_entity](/ecs/cf_destroy_entity.md) +[cf_entity_has_component](/ecs/cf_entity_has_component.md) +[cf_entity_get_component](/ecs/cf_entity_get_component.md) diff --git a/docs/ecs/cf_destroy_world.md b/docs/ecs/cf_destroy_world.md index d52c7c495..8e26cc822 100644 --- a/docs/ecs/cf_destroy_world.md +++ b/docs/ecs/cf_destroy_world.md @@ -9,16 +9,17 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Destroys the world. ```cpp void cf_destroy_world(CF_World world); ``` -## Remarks - -TODO - ## Related Pages -TODO +[CF_World](/ecs/cf_world.md) +[cf_make_world](/ecs/cf_make_world.md) +[cf_world_equals](/ecs/cf_world_equals.md) +[cf_world_push](/ecs/cf_world_push.md) +[cf_world_pop](/ecs/cf_world_pop.md) +[cf_world_peek](/ecs/cf_world_peek.md) diff --git a/docs/ecs/cf_entity_activate.md b/docs/ecs/cf_entity_activate.md index 8cb0469f6..05422d630 100644 --- a/docs/ecs/cf_entity_activate.md +++ b/docs/ecs/cf_entity_activate.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Stops updating the entity, it will not be passed into any system updates. ```cpp void cf_entity_activate(CF_Entity entity); @@ -17,4 +17,7 @@ void cf_entity_activate(CF_Entity entity); ## Related Pages -TODO +[CF_Entity](/ecs/cf_entity.md) +[cf_entity_delayed_activate](/ecs/cf_entity_delayed_activate.md) +[cf_entity_deactivate](/ecs/cf_entity_deactivate.md) +[cf_entity_is_active](/ecs/cf_entity_is_active.md) diff --git a/docs/ecs/cf_entity_begin.md b/docs/ecs/cf_entity_begin.md index 2cd1142f2..c03f04d6c 100644 --- a/docs/ecs/cf_entity_begin.md +++ b/docs/ecs/cf_entity_begin.md @@ -17,7 +17,8 @@ void cf_entity_begin(); ## Remarks -TODO +Call [cf_entity_end](/ecs/cf_entity_end.md) to finish the entity definition. Once done you may instantiate entities +of this type via [cf_make_entity](/ecs/cf_make_entity.md). ## Related Pages diff --git a/docs/ecs/cf_entity_change_type.md b/docs/ecs/cf_entity_change_type.md index 37dbdba72..101809d58 100644 --- a/docs/ecs/cf_entity_change_type.md +++ b/docs/ecs/cf_entity_change_type.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Changes the type of this entity. ```cpp void cf_entity_change_type(CF_Entity entity, const char* entity_type); @@ -17,4 +17,6 @@ void cf_entity_change_type(CF_Entity entity, const char* entity_type); ## Related Pages -TODO +[cf_entity_delayed_change_type](/ecs/cf_entity_delayed_change_type.md) +entity_get_type_string +[cf_entity_type_rename](/ecs/cf_entity_type_rename.md) diff --git a/docs/ecs/cf_entity_deactivate.md b/docs/ecs/cf_entity_deactivate.md index 6015c1d8b..d38d9b6b8 100644 --- a/docs/ecs/cf_entity_deactivate.md +++ b/docs/ecs/cf_entity_deactivate.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Activates this entity, it will be passed to system updates. ```cpp void cf_entity_deactivate(CF_Entity entity); @@ -17,4 +17,7 @@ void cf_entity_deactivate(CF_Entity entity); ## Related Pages -TODO +[CF_Entity](/ecs/cf_entity.md) +[cf_entity_delayed_activate](/ecs/cf_entity_delayed_activate.md) +[cf_entity_is_active](/ecs/cf_entity_is_active.md) +[cf_entity_activate](/ecs/cf_entity_activate.md) diff --git a/docs/ecs/cf_entity_delayed_activate.md b/docs/ecs/cf_entity_delayed_activate.md index b7611ccfd..e1babc942 100644 --- a/docs/ecs/cf_entity_delayed_activate.md +++ b/docs/ecs/cf_entity_delayed_activate.md @@ -9,12 +9,19 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Activates this entity, it will be passed to system updates. ```cpp void cf_entity_delayed_activate(CF_Entity entity); ``` +## Remarks + +The activation is delayed until the end of the frame. + ## Related Pages -TODO +[CF_Entity](/ecs/cf_entity.md) +[cf_entity_is_active](/ecs/cf_entity_is_active.md) +[cf_entity_deactivate](/ecs/cf_entity_deactivate.md) +[cf_entity_activate](/ecs/cf_entity_activate.md) diff --git a/docs/ecs/cf_entity_delayed_change_type.md b/docs/ecs/cf_entity_delayed_change_type.md index 4be5bb92e..e2c75cabf 100644 --- a/docs/ecs/cf_entity_delayed_change_type.md +++ b/docs/ecs/cf_entity_delayed_change_type.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Changes the type of this entity. ```cpp void cf_entity_delayed_change_type(CF_Entity entity, const char* entity_type); @@ -17,8 +17,14 @@ void cf_entity_delayed_change_type(CF_Entity entity, const char* entity_type); ## Remarks -CURRENTLY NOT IMPLEMENTED. +The change is delayed to the end of the frame. Since this function can clean up components +that disappear it may be beneficial to delay in order to avoid dangling references, or simplify +gameplay logic that depends on these components. + +This function can be useful for implementing certain editors. ## Related Pages -TODO +entity_get_type_string +[cf_entity_change_type](/ecs/cf_entity_change_type.md) +[cf_entity_type_rename](/ecs/cf_entity_type_rename.md) diff --git a/docs/ecs/cf_entity_delayed_deactivate.md b/docs/ecs/cf_entity_delayed_deactivate.md index c5fdedf3a..e3534efdf 100644 --- a/docs/ecs/cf_entity_delayed_deactivate.md +++ b/docs/ecs/cf_entity_delayed_deactivate.md @@ -9,12 +9,20 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Stops updating the entity, it will not be passed into any system updates. ```cpp void cf_entity_delayed_deactivate(CF_Entity entity); ``` +## Remarks + +The deactivation is delayed until the end of the frame. + ## Related Pages -TODO +[CF_Entity](/ecs/cf_entity.md) +[cf_entity_delayed_activate](/ecs/cf_entity_delayed_activate.md) +[cf_entity_deactivate](/ecs/cf_entity_deactivate.md) +[cf_entity_activate](/ecs/cf_entity_activate.md) +[cf_entity_is_active](/ecs/cf_entity_is_active.md) diff --git a/docs/ecs/cf_entity_equals.md b/docs/ecs/cf_entity_equals.md index 23f09104c..310a75f81 100644 --- a/docs/ecs/cf_entity_equals.md +++ b/docs/ecs/cf_entity_equals.md @@ -12,13 +12,11 @@ GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/inc Returns true if two [CF_Entity](/ecs/cf_entity.md)'s are equal. ```cpp -bool cf_entity_equals(CF_Entity* a, CF_Entity* b) +bool cf_entity_equals(CF_Entity a, CF_Entity b) ``` -## Remarks - -TODO - ## Related Pages -TODO +[CF_Entity](/ecs/cf_entity.md) +[cf_make_entity](/ecs/cf_make_entity.md) +[cf_destroy_entity](/ecs/cf_destroy_entity.md) diff --git a/docs/ecs/cf_entity_get_component.md b/docs/ecs/cf_entity_get_component.md index a3862ee72..b5db0188a 100644 --- a/docs/ecs/cf_entity_get_component.md +++ b/docs/ecs/cf_entity_get_component.md @@ -15,10 +15,8 @@ Returns a pointer to a specific component on an entity. void* cf_entity_get_component(CF_Entity entity, const char* component_type); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_make_entity](/ecs/cf_make_entity.md) +[cf_destroy_entity](/ecs/cf_destroy_entity.md) +[cf_entity_has_component](/ecs/cf_entity_has_component.md) diff --git a/docs/ecs/cf_entity_get_type_string.md b/docs/ecs/cf_entity_get_type_string.md index 394763a13..efe1063f9 100644 --- a/docs/ecs/cf_entity_get_type_string.md +++ b/docs/ecs/cf_entity_get_type_string.md @@ -15,10 +15,8 @@ Returns an entity's type string. const char* cf_entity_get_type_string(CF_Entity entity); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_make_entity](/ecs/cf_make_entity.md) +[cf_destroy_entity](/ecs/cf_destroy_entity.md) +[cf_entity_has_component](/ecs/cf_entity_has_component.md) diff --git a/docs/ecs/cf_entity_has_component.md b/docs/ecs/cf_entity_has_component.md index 1cd817708..61fd15ea9 100644 --- a/docs/ecs/cf_entity_has_component.md +++ b/docs/ecs/cf_entity_has_component.md @@ -15,10 +15,8 @@ Returns true if an entity has a particular component. bool cf_entity_has_component(CF_Entity entity, const char* component_type); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_make_entity](/ecs/cf_make_entity.md) +[cf_destroy_entity](/ecs/cf_destroy_entity.md) +[cf_entity_get_component](/ecs/cf_entity_get_component.md) diff --git a/docs/ecs/cf_entity_is_active.md b/docs/ecs/cf_entity_is_active.md index 16d127e1b..14506f3f6 100644 --- a/docs/ecs/cf_entity_is_active.md +++ b/docs/ecs/cf_entity_is_active.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Returns true if this entity is active (it will participate in system updates). ```cpp bool cf_entity_is_active(CF_Entity entity); @@ -17,4 +17,7 @@ bool cf_entity_is_active(CF_Entity entity); ## Related Pages -TODO +[CF_Entity](/ecs/cf_entity.md) +[cf_entity_delayed_activate](/ecs/cf_entity_delayed_activate.md) +[cf_entity_deactivate](/ecs/cf_entity_deactivate.md) +[cf_entity_activate](/ecs/cf_entity_activate.md) diff --git a/docs/ecs/cf_entity_is_type.md b/docs/ecs/cf_entity_is_type.md index 0ad544492..b5e25d7f0 100644 --- a/docs/ecs/cf_entity_is_type.md +++ b/docs/ecs/cf_entity_is_type.md @@ -15,10 +15,8 @@ Returns true if the entity is a certain type. bool cf_entity_is_type(CF_Entity entity, const char* entity_type); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_make_entity](/ecs/cf_make_entity.md) +[cf_destroy_entity](/ecs/cf_destroy_entity.md) +[cf_entity_has_component](/ecs/cf_entity_has_component.md) diff --git a/docs/ecs/cf_entity_is_valid.md b/docs/ecs/cf_entity_is_valid.md index 057d20e06..fa36fc8a3 100644 --- a/docs/ecs/cf_entity_is_valid.md +++ b/docs/ecs/cf_entity_is_valid.md @@ -15,10 +15,8 @@ Returns true if the [CF_Entity](/ecs/cf_entity.md) is a valid entity. bool cf_entity_is_valid(CF_Entity entity); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_make_entity](/ecs/cf_make_entity.md) +[cf_destroy_entity](/ecs/cf_destroy_entity.md) +[cf_entity_has_component](/ecs/cf_entity_has_component.md) diff --git a/docs/ecs/cf_entity_type_rename.md b/docs/ecs/cf_entity_type_rename.md index 912cd1c45..81d0639da 100644 --- a/docs/ecs/cf_entity_type_rename.md +++ b/docs/ecs/cf_entity_type_rename.md @@ -9,12 +9,18 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Changes the string identifier for an entity type. ```cpp void cf_entity_type_rename(const char* entity_type, const char* new_entity_type_name); ``` +## Remarks + +This function can be useful for implementing certain editors. + ## Related Pages -TODO +[cf_entity_delayed_change_type](/ecs/cf_entity_delayed_change_type.md) +[cf_entity_change_type](/ecs/cf_entity_change_type.md) +entity_get_type_string diff --git a/docs/ecs/cf_get_component_list.md b/docs/ecs/cf_get_component_list.md index c6de080b7..341ca69c6 100644 --- a/docs/ecs/cf_get_component_list.md +++ b/docs/ecs/cf_get_component_list.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Returns a list of all component types that have been defined. ```cpp dyna const char** cf_get_component_list(); @@ -17,8 +17,11 @@ dyna const char** cf_get_component_list(); ## Remarks -TODO +This is an introspective function, useful for implementing certain editors. Free it with [afree](/array/afree.md) when done. See [dyna](/array/dyna.md). ## Related Pages -TODO +[cf_is_entity_type_valid](/ecs/cf_is_entity_type_valid.md) +[cf_get_entity_list](/ecs/cf_get_entity_list.md) +[cf_get_component_list_for_entity_type](/ecs/cf_get_component_list_for_entity_type.md) +[cf_get_system_list](/ecs/cf_get_system_list.md) diff --git a/docs/ecs/cf_get_component_list_for_entity_type.md b/docs/ecs/cf_get_component_list_for_entity_type.md index 252207204..22a5675c3 100644 --- a/docs/ecs/cf_get_component_list_for_entity_type.md +++ b/docs/ecs/cf_get_component_list_for_entity_type.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Returns an array of all component types that comprise an instance of `entity_type`. ```cpp dyna const char** cf_get_component_list_for_entity_type(const char* entity_type); @@ -17,8 +17,11 @@ dyna const char** cf_get_component_list_for_entity_type(const char* entity_type) ## Remarks -TODO +This is an introspective function, useful for implementing certain editors. Free it with [afree](/array/afree.md) when done. See [dyna](/array/dyna.md). ## Related Pages -TODO +[cf_is_entity_type_valid](/ecs/cf_is_entity_type_valid.md) +[cf_get_entity_list](/ecs/cf_get_entity_list.md) +[cf_get_component_list](/ecs/cf_get_component_list.md) +[cf_get_system_list](/ecs/cf_get_system_list.md) diff --git a/docs/ecs/cf_get_components.md b/docs/ecs/cf_get_components.md index 965939773..fbeab0601 100644 --- a/docs/ecs/cf_get_components.md +++ b/docs/ecs/cf_get_components.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Returns a list of components to update, where array elements line up with each entity. ```cpp void* cf_get_components(CF_ComponentList component_list, const char* component_type); @@ -17,8 +17,16 @@ void* cf_get_components(CF_ComponentList component_list, const char* component_t ## Remarks -TODO +It's highly recommended to use the macro [CF_GET_COMPONENTS](/ecs/cf_get_components.md) to fetch component arrays. +For a full example see the [Entity Component System](https://randygaul.github.io/cute_framework/#/topics/entity_component_system) page. ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) +[cf_system_end](/ecs/cf_system_end.md) diff --git a/docs/ecs/cf_get_entities.md b/docs/ecs/cf_get_entities.md index a2b6c1a96..b20a4d00c 100644 --- a/docs/ecs/cf_get_entities.md +++ b/docs/ecs/cf_get_entities.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Fetches an array of entity handles. ```cpp CF_Entity* cf_get_entities(CF_ComponentList component_list); @@ -17,8 +17,15 @@ CF_Entity* cf_get_entities(CF_ComponentList component_list); ## Remarks -TODO +The indices of the handles line up with the indices of component lists. For a full example see the [Entity Component System](https://randygaul.github.io/cute_framework/#/topics/entity_component_system) page. ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) +[cf_system_end](/ecs/cf_system_end.md) diff --git a/docs/ecs/cf_get_entity_list.md b/docs/ecs/cf_get_entity_list.md index 93ec2b39d..ff030e5d8 100644 --- a/docs/ecs/cf_get_entity_list.md +++ b/docs/ecs/cf_get_entity_list.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Returns an array of all entity types that have been defined. ```cpp dyna const char** cf_get_entity_list(); @@ -17,8 +17,11 @@ dyna const char** cf_get_entity_list(); ## Remarks -TODO +This is an introspective function, useful for implementing certain editors. Free it with [afree](/array/afree.md) when done. See [dyna](/array/dyna.md). ## Related Pages -TODO +[cf_is_entity_type_valid](/ecs/cf_is_entity_type_valid.md) +[cf_get_component_list_for_entity_type](/ecs/cf_get_component_list_for_entity_type.md) +[cf_get_component_list](/ecs/cf_get_component_list.md) +[cf_get_system_list](/ecs/cf_get_system_list.md) diff --git a/docs/ecs/cf_get_system_list.md b/docs/ecs/cf_get_system_list.md index cacb6fb69..a16075eec 100644 --- a/docs/ecs/cf_get_system_list.md +++ b/docs/ecs/cf_get_system_list.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Returns an array of all systems that have been defined. ```cpp dyna const char** cf_get_system_list(); @@ -17,8 +17,11 @@ dyna const char** cf_get_system_list(); ## Remarks -TODO +This is an introspective function, useful for implementing certain editors. Free it with [afree](/array/afree.md) when done. See [dyna](/array/dyna.md). ## Related Pages -TODO +[cf_is_entity_type_valid](/ecs/cf_is_entity_type_valid.md) +[cf_get_entity_list](/ecs/cf_get_entity_list.md) +[cf_get_component_list](/ecs/cf_get_component_list.md) +[cf_get_component_list_for_entity_type](/ecs/cf_get_component_list_for_entity_type.md) diff --git a/docs/ecs/cf_is_entity_type_valid.md b/docs/ecs/cf_is_entity_type_valid.md index a25f121e3..bc761c819 100644 --- a/docs/ecs/cf_is_entity_type_valid.md +++ b/docs/ecs/cf_is_entity_type_valid.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Returns true if a the entity_type is valid. ```cpp bool cf_is_entity_type_valid(const char* entity_type); @@ -17,8 +17,11 @@ bool cf_is_entity_type_valid(const char* entity_type); ## Remarks -TODO +This is an introspective function, useful for implementing certain editors. ## Related Pages -TODO +[cf_get_component_list_for_entity_type](/ecs/cf_get_component_list_for_entity_type.md) +[cf_get_entity_list](/ecs/cf_get_entity_list.md) +[cf_get_component_list](/ecs/cf_get_component_list.md) +[cf_get_system_list](/ecs/cf_get_system_list.md) diff --git a/docs/ecs/cf_make_entity.md b/docs/ecs/cf_make_entity.md index 8f989fe5e..eca058484 100644 --- a/docs/ecs/cf_make_entity.md +++ b/docs/ecs/cf_make_entity.md @@ -17,8 +17,9 @@ CF_Entity cf_make_entity(const char* entity_type); ## Remarks -TODO +You must first define components and the entity layout itself. For a full example see the [Entity Component System](https://randygaul.github.io/cute_framework/#/topics/entity_component_system) page. ## Related Pages -TODO +[cf_entity_has_component](/ecs/cf_entity_has_component.md) +[cf_destroy_entity](/ecs/cf_destroy_entity.md) diff --git a/docs/ecs/cf_make_world.md b/docs/ecs/cf_make_world.md index 03c867b84..745b7dba9 100644 --- a/docs/ecs/cf_make_world.md +++ b/docs/ecs/cf_make_world.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Constructs a new entity world. ```cpp CF_World cf_make_world(); @@ -17,8 +17,14 @@ CF_World cf_make_world(); ## Remarks -TODO +Entity worlds are scopes of entity instances. Other functions like looking up an entity, or system updates, only work +on entity instances that belong to the currently active world. ## Related Pages -TODO +[CF_World](/ecs/cf_world.md) +[cf_world_equals](/ecs/cf_world_equals.md) +[cf_destroy_world](/ecs/cf_destroy_world.md) +[cf_world_push](/ecs/cf_world_push.md) +[cf_world_pop](/ecs/cf_world_pop.md) +[cf_world_peek](/ecs/cf_world_peek.md) diff --git a/docs/ecs/cf_run_systems.md b/docs/ecs/cf_run_systems.md index 590d335c4..70b6a89e6 100644 --- a/docs/ecs/cf_run_systems.md +++ b/docs/ecs/cf_run_systems.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Updates a system. ```cpp void cf_run_systems(); @@ -17,8 +17,16 @@ void cf_run_systems(); ## Remarks -TODO +All entities who have matching components will be filtered for and passed along to the system for updating. The order +of system updates is determined by the order in which they are defined by [cf_system_begin](/ecs/cf_system_begin.md). ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) +[cf_system_end](/ecs/cf_system_end.md) diff --git a/docs/ecs/cf_system_begin.md b/docs/ecs/cf_system_begin.md index 93fd72439..63b184ed6 100644 --- a/docs/ecs/cf_system_begin.md +++ b/docs/ecs/cf_system_begin.md @@ -9,16 +9,18 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Defines a new system. ```cpp void cf_system_begin(); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_system_end](/ecs/cf_system_end.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) diff --git a/docs/ecs/cf_system_end.md b/docs/ecs/cf_system_end.md index 659eb3ada..aad197872 100644 --- a/docs/ecs/cf_system_end.md +++ b/docs/ecs/cf_system_end.md @@ -9,16 +9,18 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Completes the definition of a new system. ```cpp void cf_system_end(); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) diff --git a/docs/ecs/cf_system_require_component.md b/docs/ecs/cf_system_require_component.md index d845c6b54..0eda24b66 100644 --- a/docs/ecs/cf_system_require_component.md +++ b/docs/ecs/cf_system_require_component.md @@ -9,7 +9,7 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Specifies this system will filter for and update entities with this component type. ```cpp void cf_system_require_component(const char* component_type); @@ -17,8 +17,15 @@ void cf_system_require_component(const char* component_type); ## Remarks -TODO +You should call this function once per component type this system is interested in. The system will +only update entities who have all of the specified components. ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_end](/ecs/cf_system_end.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) diff --git a/docs/ecs/cf_system_set_name.md b/docs/ecs/cf_system_set_name.md index 12bc0b37c..9a05296bf 100644 --- a/docs/ecs/cf_system_set_name.md +++ b/docs/ecs/cf_system_set_name.md @@ -9,16 +9,18 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Defines the new system's name. ```cpp void cf_system_set_name(const char* name); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_end](/ecs/cf_system_end.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) diff --git a/docs/ecs/cf_system_set_optional_post_update.md b/docs/ecs/cf_system_set_optional_post_update.md index b78adcbdd..072147ec2 100644 --- a/docs/ecs/cf_system_set_optional_post_update.md +++ b/docs/ecs/cf_system_set_optional_post_update.md @@ -9,16 +9,18 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Sets an optional update callback called once just after the system update. ```cpp void cf_system_set_optional_post_update(void (*post_update_fn)(void* udata)); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_end](/ecs/cf_system_end.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) diff --git a/docs/ecs/cf_system_set_optional_pre_update.md b/docs/ecs/cf_system_set_optional_pre_update.md index 0aaad7588..6a1df1e26 100644 --- a/docs/ecs/cf_system_set_optional_pre_update.md +++ b/docs/ecs/cf_system_set_optional_pre_update.md @@ -9,16 +9,18 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Sets an optional update callback called once just before the system update. ```cpp void cf_system_set_optional_pre_update(void (*pre_update_fn)(void* udata)); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_end](/ecs/cf_system_end.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) diff --git a/docs/ecs/cf_system_set_optional_udata.md b/docs/ecs/cf_system_set_optional_udata.md index 584a59691..0f6d338a7 100644 --- a/docs/ecs/cf_system_set_optional_udata.md +++ b/docs/ecs/cf_system_set_optional_udata.md @@ -9,16 +9,18 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Sets an optional user data pointer, passed to all system callbacks. ```cpp void cf_system_set_optional_udata(void* udata); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_set_update](/ecs/cf_system_set_update.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_end](/ecs/cf_system_end.md) diff --git a/docs/ecs/cf_system_set_update.md b/docs/ecs/cf_system_set_update.md index c5788918c..1c5154861 100644 --- a/docs/ecs/cf_system_set_update.md +++ b/docs/ecs/cf_system_set_update.md @@ -9,16 +9,18 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Sets the update function for the system. ```cpp void cf_system_set_update(CF_SystemUpdateFn* update_fn); ``` -## Remarks - -TODO - ## Related Pages -TODO +[cf_system_begin](/ecs/cf_system_begin.md) +[cf_system_set_name](/ecs/cf_system_set_name.md) +[cf_system_end](/ecs/cf_system_end.md) +[cf_system_require_component](/ecs/cf_system_require_component.md) +[cf_system_set_optional_pre_update](/ecs/cf_system_set_optional_pre_update.md) +[cf_system_set_optional_post_update](/ecs/cf_system_set_optional_post_update.md) +[cf_system_set_optional_udata](/ecs/cf_system_set_optional_udata.md) diff --git a/docs/ecs/cf_world_equals.md b/docs/ecs/cf_world_equals.md index 9222dc218..ad92b5903 100644 --- a/docs/ecs/cf_world_equals.md +++ b/docs/ecs/cf_world_equals.md @@ -9,16 +9,17 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Returns true if two worlds are equivalent. ```cpp bool cf_world_equals(CF_World a, CF_World b) ``` -## Remarks - -TODO - ## Related Pages -TODO +[CF_World](/ecs/cf_world.md) +[cf_make_world](/ecs/cf_make_world.md) +[cf_destroy_world](/ecs/cf_destroy_world.md) +[cf_world_push](/ecs/cf_world_push.md) +[cf_world_pop](/ecs/cf_world_pop.md) +[cf_world_peek](/ecs/cf_world_peek.md) diff --git a/docs/ecs/cf_world_peek.md b/docs/ecs/cf_world_peek.md index 7d2398c20..b57104008 100644 --- a/docs/ecs/cf_world_peek.md +++ b/docs/ecs/cf_world_peek.md @@ -9,16 +9,17 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Returns the currently active world. ```cpp CF_World cf_world_peek(); ``` -## Remarks - -TODO - ## Related Pages -TODO +[CF_World](/ecs/cf_world.md) +[cf_make_world](/ecs/cf_make_world.md) +[cf_destroy_world](/ecs/cf_destroy_world.md) +[cf_world_push](/ecs/cf_world_push.md) +[cf_world_pop](/ecs/cf_world_pop.md) +[cf_world_equals](/ecs/cf_world_equals.md) diff --git a/docs/ecs/cf_world_pop.md b/docs/ecs/cf_world_pop.md index c42ae6649..053d5eb16 100644 --- a/docs/ecs/cf_world_pop.md +++ b/docs/ecs/cf_world_pop.md @@ -9,16 +9,17 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Pops the current world and restores the previous one. ```cpp CF_World cf_world_pop(); ``` -## Remarks - -TODO - ## Related Pages -TODO +[CF_World](/ecs/cf_world.md) +[cf_make_world](/ecs/cf_make_world.md) +[cf_destroy_world](/ecs/cf_destroy_world.md) +[cf_world_push](/ecs/cf_world_push.md) +[cf_world_equals](/ecs/cf_world_equals.md) +[cf_world_peek](/ecs/cf_world_peek.md) diff --git a/docs/ecs/cf_world_push.md b/docs/ecs/cf_world_push.md index c780acb4c..29ebc9582 100644 --- a/docs/ecs/cf_world_push.md +++ b/docs/ecs/cf_world_push.md @@ -9,16 +9,17 @@ Category: [ecs](/api_reference?id=ecs) GitHub: [cute_ecs.h](https://github.com/RandyGaul/cute_framework/blob/master/include/cute_ecs.h) --- -TODO +Pushes a world. ```cpp void cf_world_push(CF_World world); ``` -## Remarks - -TODO - ## Related Pages -TODO +[CF_World](/ecs/cf_world.md) +[cf_make_world](/ecs/cf_make_world.md) +[cf_destroy_world](/ecs/cf_destroy_world.md) +[cf_world_equals](/ecs/cf_world_equals.md) +[cf_world_pop](/ecs/cf_world_pop.md) +[cf_world_peek](/ecs/cf_world_peek.md) diff --git a/docs/topics/drawing.md b/docs/topics/drawing.md index cfe9fa0c3..0b133cdbe 100644 --- a/docs/topics/drawing.md +++ b/docs/topics/drawing.md @@ -14,7 +14,6 @@ CF can render a variety of shape types: - Line segment - Polyline - Capsule -- Arc - Bezier polyline The shape renderer in CF has a few extra features that nearly all shapes take advantage of: diff --git a/include/cute_draw.h b/include/cute_draw.h index 6b796a413..9b58a646a 100644 --- a/include/cute_draw.h +++ b/include/cute_draw.h @@ -139,7 +139,7 @@ CF_INLINE void cf_draw_box_fill2(CF_V2 p0, CF_V2 p1, CF_V2 p2, CF_V2 p3, float c * @brief Draws a circle wireframe. * @param circle The circle. * @param thickness The thickness of each line to draw. - * @related cf_draw_circle cf_draw_circle2 cf_draw_circle_fill cf_draw_circle_fill2 cf_draw_arc + * @related cf_draw_circle cf_draw_circle2 cf_draw_circle_fill cf_draw_circle_fill2 */ CF_API void CF_CALL cf_draw_circle(CF_Circle circle, float thickness); @@ -150,7 +150,7 @@ CF_API void CF_CALL cf_draw_circle(CF_Circle circle, float thickness); * @param p Center of the circle. * @param r Radius of the circle. * @param thickness The thickness of each line to draw. - * @related cf_draw_circle cf_draw_circle2 cf_draw_circle_fill cf_draw_circle_fill2 cf_draw_arc + * @related cf_draw_circle cf_draw_circle2 cf_draw_circle_fill cf_draw_circle_fill2 */ CF_API void CF_CALL cf_draw_circle2(CF_V2 p, float r, float thickness); @@ -159,7 +159,7 @@ CF_API void CF_CALL cf_draw_circle2(CF_V2 p, float r, float thickness); * @category draw * @brief Draws a circle. * @param circle The circle. - * @related cf_draw_circle cf_draw_circle2 cf_draw_circle_fill cf_draw_circle_fill2 cf_draw_arc + * @related cf_draw_circle cf_draw_circle2 cf_draw_circle_fill cf_draw_circle_fill2 */ CF_API void CF_CALL cf_draw_circle_fill(CF_Circle circle); @@ -169,23 +169,10 @@ CF_API void CF_CALL cf_draw_circle_fill(CF_Circle circle); * @brief Draws a circle. * @param p Center of the circle. * @param r Radius of the circle. - * @related cf_draw_circle cf_draw_circle2 cf_draw_circle_fill cf_draw_circle_fill2 cf_draw_arc + * @related cf_draw_circle cf_draw_circle2 cf_draw_circle_fill cf_draw_circle_fill2 */ CF_API void CF_CALL cf_draw_circle_fill2(CF_V2 p, float r); -/** - * @function cf_draw_arc - * @category draw - * @brief Draws an arc of a circle wireframe. - * @param p Center of the arc. - * @param center_of_arc Radius of the circle. - * @param range Angle the arc covers. - * @param iters Number of edges used for the circle. More looks smoother, but renders slower. - * @param thickness The thickness of each line to draw. - * @related cf_draw_circle cf_draw_circle2 cf_draw_circle_fill cf_draw_circle_fill2 cf_draw_arc - */ -CF_API void CF_CALL cf_draw_arc(CF_V2 p, CF_V2 center_of_arc, float range, int iters, float thickness); - /** * @function cf_draw_capsule * @category draw @@ -1525,7 +1512,6 @@ CF_INLINE void draw_circle(Circle circle, float thickness = 1.0f) { cf_draw_circ CF_INLINE void draw_circle(v2 p, float r, float thickness = 1.0f) { cf_draw_circle2(p, r, thickness); } CF_INLINE void draw_circle_fill(Circle circle) { cf_draw_circle_fill(circle); } CF_INLINE void draw_circle_fill(v2 p, float r) { cf_draw_circle_fill2(p, r); } -CF_INLINE void draw_arc(v2 p, v2 center_of_arc, float range, int iters = 20, float thickness = 1.0f) { cf_draw_arc(p, center_of_arc, range, iters, thickness); } CF_INLINE void draw_capsule(Capsule capsule, float thickness = 1.0f) { cf_draw_capsule(capsule, thickness); } CF_INLINE void draw_capsule(v2 p0, v2 p1, float r, float thickness = 1.0f) { cf_draw_capsule2(p0, p1, r, thickness); } CF_INLINE void draw_capsule_fill(Capsule capsule) { cf_draw_capsule_fill(capsule); } diff --git a/include/cute_ecs.h b/include/cute_ecs.h index 2c5b79982..5f0ef36b7 100644 --- a/include/cute_ecs.h +++ b/include/cute_ecs.h @@ -102,7 +102,8 @@ static CF_World CF_INVALID_WORLD = { 0 }; * @function cf_entity_begin * @category ecs * @brief Begins the definition of a new entity type. - * @remarks TODO + * @remarks Call `cf_entity_end` to finish the entity definition. Once done you may instantiate entities + * of this type via `cf_make_entity`. * @related CF_Entity cf_entity_begin cf_entity_set_name cf_entity_add_component cf_entity_end cf_make_entity */ CF_API void CF_CALL cf_entity_begin(); @@ -142,8 +143,8 @@ CF_API void CF_CALL cf_entity_end(); * @function cf_make_entity * @category ecs * @brief Returns a newly constructed entity instance. - * @remarks TODO - * @related TODO + * @remarks You must first define components and the entity layout itself. For a full example see the [Entity Component System](https://randygaul.github.io/cute_framework/#/topics/entity_component_system) page. + * @related cf_make_entity cf_destroy_entity cf_entity_has_component */ CF_API CF_Entity CF_CALL cf_make_entity(const char* entity_type); @@ -151,8 +152,7 @@ CF_API CF_Entity CF_CALL cf_make_entity(const char* entity_type); * @function cf_entity_is_valid * @category ecs * @brief Returns true if the `CF_Entity` is a valid entity. - * @remarks TODO - * @related TODO + * @related cf_make_entity cf_destroy_entity cf_entity_has_component */ CF_API bool CF_CALL cf_entity_is_valid(CF_Entity entity); @@ -160,8 +160,7 @@ CF_API bool CF_CALL cf_entity_is_valid(CF_Entity entity); * @function cf_entity_is_type * @category ecs * @brief Returns true if the entity is a certain type. - * @remarks TODO - * @related TODO + * @related cf_make_entity cf_destroy_entity cf_entity_has_component */ CF_API bool CF_CALL cf_entity_is_type(CF_Entity entity, const char* entity_type); @@ -169,8 +168,7 @@ CF_API bool CF_CALL cf_entity_is_type(CF_Entity entity, const char* entity_type) * @function cf_entity_get_type_string * @category ecs * @brief Returns an entity's type string. - * @remarks TODO - * @related TODO + * @related cf_make_entity cf_destroy_entity cf_entity_has_component */ CF_API const char* CF_CALL cf_entity_get_type_string(CF_Entity entity); @@ -178,8 +176,7 @@ CF_API const char* CF_CALL cf_entity_get_type_string(CF_Entity entity); * @function cf_entity_has_component * @category ecs * @brief Returns true if an entity has a particular component. - * @remarks TODO - * @related TODO + * @related cf_make_entity cf_destroy_entity cf_entity_has_component cf_entity_get_component */ CF_API bool CF_CALL cf_entity_has_component(CF_Entity entity, const char* component_type); @@ -187,8 +184,7 @@ CF_API bool CF_CALL cf_entity_has_component(CF_Entity entity, const char* compon * @function cf_entity_get_component * @category ecs * @brief Returns a pointer to a specific component on an entity. - * @remarks TODO - * @related TODO + * @related cf_make_entity cf_destroy_entity cf_entity_has_component cf_entity_get_component */ CF_API void* CF_CALL cf_entity_get_component(CF_Entity entity, const char* component_type); @@ -196,8 +192,7 @@ CF_API void* CF_CALL cf_entity_get_component(CF_Entity entity, const char* compo * @function cf_destroy_entity_delayed * @category ecs * @brief Marks a specific entity for delayed destruction. - * @remarks TODO - * @related TODO + * @related cf_make_entity cf_destroy_entity cf_entity_has_component cf_entity_get_component */ CF_API void CF_CALL cf_destroy_entity_delayed(CF_Entity entity); @@ -205,8 +200,7 @@ CF_API void CF_CALL cf_destroy_entity_delayed(CF_Entity entity); * @function cf_destroy_entity * @category ecs * @brief Destroys a specific entity right now. - * @remarks TODO - * @related TODO + * @related cf_make_entity cf_destroy_entity cf_entity_has_component cf_entity_get_component */ CF_API void CF_CALL cf_destroy_entity(CF_Entity entity); @@ -214,235 +208,232 @@ CF_API void CF_CALL cf_destroy_entity(CF_Entity entity); * @function cf_entity_equals * @category ecs * @brief Returns true if two `CF_Entity`'s are equal. - * @remarks TODO - * @related TODO + * @related CF_Entity cf_make_entity cf_destroy_entity */ -CF_INLINE bool cf_entity_equals(CF_Entity* a, CF_Entity* b) { return a->handle == b->handle; } +CF_INLINE bool cf_entity_equals(CF_Entity a, CF_Entity b) { return a.handle == b.handle; } /** * @function cf_entity_delayed_deactivate * @category ecs - * @brief TODO - * @related TODO + * @brief Stops updating the entity, it will not be passed into any system updates. + * @remarks The deactivation is delayed until the end of the frame. + * @related CF_Entity cf_entity_delayed_activate cf_entity_deactivate cf_entity_activate cf_entity_is_active */ CF_API void CF_CALL cf_entity_delayed_deactivate(CF_Entity entity); /** * @function cf_entity_delayed_activate * @category ecs - * @brief TODO - * @related TODO + * @brief Activates this entity, it will be passed to system updates. + * @remarks The activation is delayed until the end of the frame. + * @related CF_Entity cf_entity_delayed_activate cf_entity_deactivate cf_entity_activate cf_entity_is_active */ CF_API void CF_CALL cf_entity_delayed_activate(CF_Entity entity); /** * @function cf_entity_deactivate * @category ecs - * @brief TODO - * @related TODO + * @brief Activates this entity, it will be passed to system updates. + * @related CF_Entity cf_entity_delayed_activate cf_entity_deactivate cf_entity_activate cf_entity_is_active */ CF_API void CF_CALL cf_entity_deactivate(CF_Entity entity); /** * @function cf_entity_activate * @category ecs - * @brief TODO - * @related TODO + * @brief Stops updating the entity, it will not be passed into any system updates. + * @related CF_Entity cf_entity_delayed_activate cf_entity_deactivate cf_entity_activate cf_entity_is_active */ CF_API void CF_CALL cf_entity_activate(CF_Entity entity); /** * @function cf_entity_is_active * @category ecs - * @brief TODO - * @related TODO + * @brief Returns true if this entity is active (it will participate in system updates). + * @related CF_Entity cf_entity_delayed_activate cf_entity_deactivate cf_entity_activate cf_entity_is_active */ CF_API bool CF_CALL cf_entity_is_active(CF_Entity entity); /** * @function cf_entity_delayed_change_type * @category ecs - * @brief TODO - * @remarks CURRENTLY NOT IMPLEMENTED. - * @related TODO + * @brief Changes the type of this entity. + * @remarks The change is delayed to the end of the frame. Since this function can clean up components + * that disappear it may be beneficial to delay in order to avoid dangling references, or simplify + * gameplay logic that depends on these components. + * + * This function can be useful for implementing certain editors. + * @related cf_entity_delayed_change_type cf_entity_change_type cf_entity_type_rename entity_get_type_string */ CF_API void CF_CALL cf_entity_delayed_change_type(CF_Entity entity, const char* entity_type); /** * @function cf_entity_change_type * @category ecs - * @brief TODO - * @related TODO + * @brief Changes the type of this entity. + * @related cf_entity_delayed_change_type cf_entity_change_type cf_entity_type_rename entity_get_type_string */ CF_API void CF_CALL cf_entity_change_type(CF_Entity entity, const char* entity_type); /** * @function cf_entity_type_rename * @category ecs - * @brief TODO - * @related TODO + * @brief Changes the string identifier for an entity type. + * @remarks This function can be useful for implementing certain editors. + * @related cf_entity_delayed_change_type cf_entity_change_type cf_entity_type_rename entity_get_type_string */ CF_API void CF_CALL cf_entity_type_rename(const char* entity_type, const char* new_entity_type_name); /** * @function cf_component_begin * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Beings the defnition of a new component type. + * @remarks Once `cf_component_end` is called you may instantiate components of this type when creating entities. + * @related cf_component_begin cf_component_set_name cf_component_set_size cf_component_set_optional_initializer cf_component_set_optional_cleanup cf_component_end */ CF_API void CF_CALL cf_component_begin(); /** * @function cf_component_set_name * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Defines the name of this new component type. + * @related cf_component_begin cf_component_set_name cf_component_set_size cf_component_set_optional_initializer cf_component_set_optional_cleanup cf_component_end */ CF_API void CF_CALL cf_component_set_name(const char* name); /** * @function cf_component_set_size * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Sets the size in bytes of this new component type. + * @related cf_component_begin cf_component_set_name cf_component_set_size cf_component_set_optional_initializer cf_component_set_optional_cleanup cf_component_end */ CF_API void CF_CALL cf_component_set_size(size_t size); /** * @function cf_component_set_optional_initializer * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Sets an optional initializer callback, called whenever a component of this type is instantiated. + * @related cf_component_begin cf_component_set_name cf_component_set_size cf_component_set_optional_initializer cf_component_set_optional_cleanup cf_component_end */ CF_API void CF_CALL cf_component_set_optional_initializer(CF_ComponentFn* initializer, void* udata); /** * @function cf_component_set_optional_cleanup * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Sets an optional cleanup callback, called whenever a component of this type is free'd. + * @related cf_component_begin cf_component_set_name cf_component_set_size cf_component_set_optional_initializer cf_component_set_optional_cleanup cf_component_end */ CF_API void CF_CALL cf_component_set_optional_cleanup(CF_ComponentFn* cleanup, void* udata); /** * @function cf_component_end * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Completes the definition of this new component type. + * @related cf_component_begin cf_component_set_name cf_component_set_size cf_component_set_optional_initializer cf_component_set_optional_cleanup cf_component_end */ CF_API void CF_CALL cf_component_end(); /** * @function cf_component_rename * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Changes the name of this component type. + * @remarks This is useful for implementing certain editors. + * @related cf_component_begin cf_component_set_name cf_component_set_size cf_component_set_optional_initializer cf_component_set_optional_cleanup cf_component_end */ CF_API void CF_CALL cf_component_rename(const char* component_name, const char* new_component_name); /** * @function cf_system_begin * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Defines a new system. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void CF_CALL cf_system_begin(); /** * @function cf_system_set_name * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Defines the new system's name. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void CF_CALL cf_system_set_name(const char* name); /** * @function cf_system_set_update * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Sets the update function for the system. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void CF_CALL cf_system_set_update(CF_SystemUpdateFn* update_fn); /** * @function cf_system_require_component * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Specifies this system will filter for and update entities with this component type. + * @remarks You should call this function once per component type this system is interested in. The system will + * only update entities who have all of the specified components. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void CF_CALL cf_system_require_component(const char* component_type); /** * @function cf_system_set_optional_pre_update * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Sets an optional update callback called once just before the system update. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void CF_CALL cf_system_set_optional_pre_update(void (*pre_update_fn)(void* udata)); /** * @function cf_system_set_optional_post_update * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Sets an optional update callback called once just after the system update. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void CF_CALL cf_system_set_optional_post_update(void (*post_update_fn)(void* udata)); /** * @function cf_system_set_optional_udata * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Sets an optional user data pointer, passed to all system callbacks. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void CF_CALL cf_system_set_optional_udata(void* udata); /** * @function cf_system_end * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Completes the definition of a new system. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void CF_CALL cf_system_end(); /** * @function cf_run_systems * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Updates a system. + * @remarks All entities who have matching components will be filtered for and passed along to the system for updating. The order + * of system updates is determined by the order in which they are defined by `cf_system_begin`. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void CF_CALL cf_run_systems(); /** * @function cf_get_components * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Returns a list of components to update, where array elements line up with each entity. + * @remarks It's highly recommended to use the macro `CF_GET_COMPONENTS` to fetch component arrays. + * For a full example see the [Entity Component System](https://randygaul.github.io/cute_framework/#/topics/entity_component_system) page. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API void* CF_CALL cf_get_components(CF_ComponentList component_list, const char* component_type); /** * @function cf_get_entities * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Fetches an array of entity handles. + * @remarks The indices of the handles line up with the indices of component lists. For a full example see the [Entity Component System](https://randygaul.github.io/cute_framework/#/topics/entity_component_system) page. + * @related cf_system_begin cf_system_set_name cf_system_set_update cf_system_require_component cf_system_set_optional_pre_update cf_system_set_optional_post_update cf_system_set_optional_udata cf_system_end */ CF_API CF_Entity* CF_CALL cf_get_entities(CF_ComponentList component_list); #define CF_GET_COMPONENTS(component_list, T) (T*)cf_get_components(component_list, #T) @@ -450,99 +441,95 @@ CF_API CF_Entity* CF_CALL cf_get_entities(CF_ComponentList component_list); /** * @function cf_make_world * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Constructs a new entity world. + * @remarks Entity worlds are scopes of entity instances. Other functions like looking up an entity, or system updates, only work + * on entity instances that belong to the currently active world. + * @related CF_World cf_make_world cf_destroy_world cf_world_push cf_world_pop cf_world_peek cf_world_equals */ CF_API CF_World CF_CALL cf_make_world(); /** * @function cf_destroy_world * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Destroys the world. + * @related CF_World cf_make_world cf_destroy_world cf_world_push cf_world_pop cf_world_peek cf_world_equals */ CF_API void CF_CALL cf_destroy_world(CF_World world); /** * @function cf_world_push * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Pushes a world. + * @related CF_World cf_make_world cf_destroy_world cf_world_push cf_world_pop cf_world_peek cf_world_equals */ CF_API void CF_CALL cf_world_push(CF_World world); /** * @function cf_world_pop * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Pops the current world and restores the previous one. + * @related CF_World cf_make_world cf_destroy_world cf_world_push cf_world_pop cf_world_peek cf_world_equals */ CF_API CF_World CF_CALL cf_world_pop(); /** * @function cf_world_peek * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Returns the currently active world. + * @related CF_World cf_make_world cf_destroy_world cf_world_push cf_world_pop cf_world_peek cf_world_equals */ CF_API CF_World CF_CALL cf_world_peek(); /** * @function cf_world_equals * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Returns true if two worlds are equivalent. + * @related CF_World cf_make_world cf_destroy_world cf_world_push cf_world_pop cf_world_peek cf_world_equals */ CF_INLINE bool cf_world_equals(CF_World a, CF_World b) { return a.id == b.id; } /** * @function cf_is_entity_type_valid * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Returns true if a the entity_type is valid. + * @remarks This is an introspective function, useful for implementing certain editors. + * @related cf_is_entity_type_valid cf_get_entity_list cf_get_component_list cf_get_system_list cf_get_component_list_for_entity_type */ CF_API bool CF_CALL cf_is_entity_type_valid(const char* entity_type); /** * @function cf_get_entity_list * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Returns an array of all entity types that have been defined. + * @remarks This is an introspective function, useful for implementing certain editors. Free it with `afree` when done. See `dyna`. + * @related cf_is_entity_type_valid cf_get_entity_list cf_get_component_list cf_get_system_list cf_get_component_list_for_entity_type */ CF_API dyna const char** CF_CALL cf_get_entity_list(); /** * @function cf_get_component_list * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Returns a list of all component types that have been defined. + * @remarks This is an introspective function, useful for implementing certain editors. Free it with `afree` when done. See `dyna`. + * @related cf_is_entity_type_valid cf_get_entity_list cf_get_component_list cf_get_system_list cf_get_component_list_for_entity_type */ CF_API dyna const char** CF_CALL cf_get_component_list(); /** * @function cf_get_system_list * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Returns an array of all systems that have been defined. + * @remarks This is an introspective function, useful for implementing certain editors. Free it with `afree` when done. See `dyna`. + * @related cf_is_entity_type_valid cf_get_entity_list cf_get_component_list cf_get_system_list cf_get_component_list_for_entity_type */ CF_API dyna const char** CF_CALL cf_get_system_list(); /** * @function cf_get_component_list_for_entity_type * @category ecs - * @brief TODO - * @remarks TODO - * @related TODO + * @brief Returns an array of all component types that comprise an instance of `entity_type`. + * @remarks This is an introspective function, useful for implementing certain editors. Free it with `afree` when done. See `dyna`. + * @related cf_is_entity_type_valid cf_get_entity_list cf_get_component_list cf_get_system_list cf_get_component_list_for_entity_type */ CF_API dyna const char** CF_CALL cf_get_component_list_for_entity_type(const char* entity_type); diff --git a/include/cute_version.h b/include/cute_version.h index b5b10b160..a93640eb0 100644 --- a/include/cute_version.h +++ b/include/cute_version.h @@ -13,7 +13,7 @@ //-------------------------------------------------------------------------------------------------- // C API -#define CF_VERSION_STRING_COMPILED "Cute Framework Version 0.0" +#define CF_VERSION_STRING_COMPILED "Cute Framework Version 1.0" #ifdef __cplusplus extern "C" { diff --git a/libraries/cute/cute_aseprite.h b/libraries/cute/cute_aseprite.h index 8401f266f..216f38088 100644 --- a/libraries/cute/cute_aseprite.h +++ b/libraries/cute/cute_aseprite.h @@ -3,7 +3,7 @@ Licensing information can be found at the end of the file. ------------------------------------------------------------------------------ - cute_aseprite.h - v1.02 + cute_aseprite.h - v1.04 To create implementation (the function definitions) #define CUTE_ASEPRITE_IMPLEMENTATION @@ -12,7 +12,7 @@ SUMMARY - cute_asesprite.h is a single-file header that implements some functions to + cute_aseprite.h is a single-file header that implements some functions to parse .ase/.aseprite files. The entire file is parsed all at once and some structs are filled out then handed back to you. @@ -45,6 +45,8 @@ 1.01 (08/31/2020) fixed memleaks, tag parsing bug (crash), blend bugs 1.02 (02/05/2022) fixed icc profile parse bug, support transparent pal- ette index, can parse 1.3 files (no tileset support) + 1.03 (11/27/2023) fixed slice pivot parse bug + 1.04 (02/20/2024) chunck 0x0004 support */ /* @@ -63,7 +65,7 @@ for (int i = 0; i < ase->frame_count; ++i) { ase_frame_t* frame = ase->frames + i; - anim.add_frame(frame->duration, frame->pixels); + anim.add_frame(frame->duration_milliseconds, frame->pixels); } @@ -121,7 +123,6 @@ typedef struct ase_udata_t ase_udata_t; typedef struct ase_cel_extra_chunk_t ase_cel_extra_chunk_t; typedef struct ase_color_profile_t ase_color_profile_t; typedef struct ase_fixed_t ase_fixed_t; -typedef struct ase_cel_extra_chunk_t ase_cel_extra_chunk_t; struct ase_color_t { @@ -212,6 +213,7 @@ struct ase_tag_t int from_frame; int to_frame; ase_animation_direction_t loop_animation_direction; + int repeat; uint8_t r, g, b; const char* name; ase_udata_t udata; @@ -347,16 +349,43 @@ struct ase_t #define CUTE_ASEPRITE_ASSERT assert #endif -#if !defined(CUTE_ASEPRITE_STDIO) - #include // fopen - #define CUTE_ASEPRITE_STDIO +#if !defined(CUTE_ASEPRITE_SEEK_SET) + #include // SEEK_SET #define CUTE_ASEPRITE_SEEK_SET SEEK_SET +#endif + +#if !defined(CUTE_ASEPRITE_SEEK_END) + #include // SEEK_END #define CUTE_ASEPRITE_SEEK_END SEEK_END +#endif + +#if !defined(CUTE_ASEPRITE_FILE) + #include // FILE #define CUTE_ASEPRITE_FILE FILE +#endif + +#if !defined(CUTE_ASEPRITE_FOPEN) + #include // fopen #define CUTE_ASEPRITE_FOPEN fopen +#endif + +#if !defined(CUTE_ASEPRITE_FSEEK) + #include // fseek #define CUTE_ASEPRITE_FSEEK fseek +#endif + +#if !defined(CUTE_ASEPRITE_FREAD) + #include // fread #define CUTE_ASEPRITE_FREAD fread +#endif + +#if !defined(CUTE_ASEPRITE_FTELL) + #include // ftell #define CUTE_ASEPRITE_FTELL ftell +#endif + +#if !defined(CUTE_ASEPRITE_FCLOSE) + #include // fclose #define CUTE_ASEPRITE_FCLOSE fclose #endif @@ -501,7 +530,7 @@ static uint32_t s_build(deflate_t* s, uint32_t* tree, uint8_t* lens, int sym_cou first[n] = first[n - 1] + counts[n - 1]; } - for (int i = 0; i < sym_count; ++i) + for (uint32_t i = 0; i < (uint32_t)sym_count; ++i) { uint8_t len = lens[i]; @@ -529,7 +558,8 @@ static int s_stored(deflate_t* s) // read LEN and NLEN, should complement each other uint16_t LEN = (uint16_t)s_read_bits(s, 16); uint16_t NLEN = (uint16_t)s_read_bits(s, 16); - CUTE_ASEPRITE_CHECK(LEN == (uint16_t)(~NLEN), "Failed to find LEN and NLEN as complements within stored (uncompressed) stream."); + uint16_t TILDE_NLEN = ~NLEN; + CUTE_ASEPRITE_CHECK(LEN == TILDE_NLEN, "Failed to find LEN and NLEN as complements within stored (uncompressed) stream."); CUTE_ASEPRITE_CHECK(s->bits_left / 8 <= (int)LEN, "Stored block extends beyond end of input stream."); p = s_ptr(s); CUTE_ASEPRITE_MEMCPY(s->out, p, LEN); @@ -656,7 +686,7 @@ static int s_inflate(const void* in, int in_bytes, void* out, int out_bytes, voi s->bits_left = in_bytes * 8; // s->words is the in-pointer rounded up to a multiple of 4 - int first_bytes = (int)((((size_t)in + 3) & ~3) - (size_t)in); + int first_bytes = (int)((((size_t)in + 3) & (size_t)(~3)) - (size_t)in); s->words = (uint32_t*)((char*)in + first_bytes); s->word_count = (in_bytes - first_bytes) / 4; int last_bytes = ((in_bytes - first_bytes) & 3); @@ -770,8 +800,8 @@ static uint64_t s_read_uint64(ase_state_t* s) } #endif -static int16_t s_read_int16(ase_state_t* s) { return (int16_t)s_read_uint16(s); } -static int16_t s_read_int32(ase_state_t* s) { return (int32_t)s_read_uint32(s); } +#define s_read_int16(s) (int16_t)s_read_uint16(s) +#define s_read_int32(s) (int32_t)s_read_uint32(s) #ifdef CUTE_ASPRITE_S_READ_BYTES // s_read_bytes() is not currently used. @@ -882,7 +912,10 @@ static ase_color_t s_color(ase_t* ase, void* src, int index) CUTE_ASEPRITE_ASSERT(ase->mode == ASE_MODE_INDEXED); uint8_t palette_index = ((uint8_t*)src)[index]; if (palette_index == ase->transparent_palette_entry_index) { - result = { 0, 0, 0, 0 }; + result.r = 0; + result.g = 0; + result.b = 0; + result.a = 0; } else { result = ase->palette.entries[palette_index].color; } @@ -895,7 +928,7 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct ase_t* ase = (ase_t*)CUTE_ASEPRITE_ALLOC(sizeof(ase_t), mem_ctx); CUTE_ASEPRITE_MEMSET(ase, 0, sizeof(*ase)); - ase_state_t state = { 0 }; + ase_state_t state = { 0, 0, 0 }; ase_state_t* s = &state; s->in = (uint8_t*)memory; s->end = s->in + size; @@ -959,6 +992,30 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct uint8_t* chunk_start = s->in; switch (chunk_type) { + case 0x0004: // Old Palette chunk (used when there are no colors with alpha in the palette) + { + uint16_t nbPackets = s_read_uint16(s); + for (uint16_t k = 0; k < nbPackets; k++) { + uint16_t maxColor = 0; + uint16_t skip = (uint16_t)s_read_uint8(s); + uint16_t nbColors = (uint16_t)s_read_uint8(s); + if (nbColors == 0) nbColors = 256; + + for (uint16_t l = 0; l < nbColors; l++) { + ase_palette_entry_t entry; + entry.color.r = s_read_uint8(s); + entry.color.g = s_read_uint8(s); + entry.color.b = s_read_uint8(s); + entry.color.a = 255; + entry.color_name = NULL; + ase->palette.entries[skip + l] = entry; + if (skip + l > maxColor) maxColor = skip + l; + } + + ase->palette.entry_count = maxColor+1; + } + + } break; case 0x2004: // Layer chunk. { CUTE_ASEPRITE_ASSERT(ase->layer_count < CUTE_ASEPRITE_MAX_LAYERS); @@ -1063,17 +1120,16 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct s_skip(s, 8); // For future (set to zero). CUTE_ASEPRITE_ASSERT(ase->tag_count < CUTE_ASEPRITE_MAX_TAGS); for (int k = 0; k < ase->tag_count; ++k) { - ase_tag_t tag; - tag.from_frame = (int)s_read_uint16(s); - tag.to_frame = (int)s_read_uint16(s); - tag.loop_animation_direction = (ase_animation_direction_t)s_read_uint8(s); - s_skip(s, 8); // For future (set to zero). - tag.r = s_read_uint8(s); - tag.g = s_read_uint8(s); - tag.b = s_read_uint8(s); + ase->tags[k].from_frame = (int)s_read_uint16(s); + ase->tags[k].to_frame = (int)s_read_uint16(s); + ase->tags[k].loop_animation_direction = (ase_animation_direction_t)s_read_uint8(s); + ase->tags[k].repeat = s_read_uint16(s); + s_skip(s, 6); // For future (set to zero). + ase->tags[k].r = s_read_uint8(s); + ase->tags[k].g = s_read_uint8(s); + ase->tags[k].b = s_read_uint8(s); s_skip(s, 1); // Extra byte (zero). - tag.name = s_read_string(s); - ase->tags[k] = tag; + ase->tags[k].name = s_read_string(s); } was_on_tags = 1; } break; @@ -1097,6 +1153,7 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct } else { entry.color_name = NULL; } + CUTE_ASEPRITE_ASSERT(k < CUTE_ASEPRITE_MAX_PALETTE_ENTRIES); ase->palette.entries[k] = entry; } } break; @@ -1129,7 +1186,8 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct s_skip(s, sizeof(uint32_t)); // Reserved. const char* name = s_read_string(s); for (int k = 0; k < (int)slice_count; ++k) { - ase_slice_t slice = { 0 }; + ase_slice_t slice; + CUTE_ASEPRITE_MEMSET(&slice, 0, sizeof(slice)); slice.name = name; slice.frame_number = (int)s_read_uint32(s); slice.origin_x = (int)s_read_int32(s); @@ -1143,7 +1201,8 @@ ase_t* cute_aseprite_load_from_memory(const void* memory, int size, void* mem_ct slice.center_y = (int)s_read_int32(s); slice.center_w = (int)s_read_uint32(s); slice.center_h = (int)s_read_uint32(s); - } else if (flags & 2) { + } + if (flags & 2) { // Has pivot information. slice.has_pivot = 1; slice.pivot_x = (int)s_read_int32(s); diff --git a/libraries/cute/cute_c2.h b/libraries/cute/cute_c2.h index 931a440f7..274a6d656 100644 --- a/libraries/cute/cute_c2.h +++ b/libraries/cute/cute_c2.h @@ -358,14 +358,14 @@ typedef struct c2GJKCache CUTE_C2_API float c2GJK(const void* A, C2_TYPE typeA, const c2x* ax_ptr, const void* B, C2_TYPE typeB, const c2x* bx_ptr, c2v* outA, c2v* outB, int use_radius, int* iterations, c2GJKCache* cache); // Stores results of a time of impact calculation done by `c2TOI`. -struct c2TOIResult +typedef struct c2TOIResult { int hit; // 1 if shapes were touching at the TOI, 0 if they never hit. float toi; // The time of impact between two shapes. c2v n; // Surface normal from shape A to B at the time of impact. c2v p; // Point of contact between shapes A and B at time of impact. int iterations; // Number of iterations the solver underwent. -}; +} c2TOIResult; // This is an advanced function, intended to be used by people who know what they're doing. // @@ -1114,10 +1114,15 @@ c2TOIResult c2TOI(const void* A, C2_TYPE typeA, const c2x* ax_ptr, c2v vA, const float rA = pA.radius; float rB = pB.radius; float radius = rA + rB; + if (!use_radius) { + rA = 0; + rB = 0; + radius = 0; + } float tolerance = 1.0e-4f; c2TOIResult result; - result.hit = false; + result.hit = 0; result.n = c2V(0, 0); result.p = c2V(0, 0); result.toi = 1.0f; @@ -1165,15 +1170,15 @@ c2TOIResult c2TOI(const void* A, C2_TYPE typeA, const c2x* ax_ptr, c2v vA, const } if (result.iterations == 0) { - result.hit = false; + result.hit = 0; } else { - result.n = c2SafeNorm(c2Neg(v)); + if (c2Dot(v, v) > 0) result.n = c2SafeNorm(c2Neg(v)); int i = c2Support(pA.verts, pA.count, c2MulrvT(ax.r, result.n)); c2v p = c2Mulxv(ax, pA.verts[i]); - if (use_radius) p = c2Add(c2Add(p, c2Mulvs(result.n, rA)), c2Mulvs(vA, t)); + p = c2Add(c2Add(p, c2Mulvs(result.n, rA)), c2Mulvs(vA, t)); result.p = p; result.toi = t; - result.hit = true; + result.hit = 1; } return result; @@ -1385,7 +1390,7 @@ int c2CircleToPoint(c2Circle A, c2v B) return d2 < A.r * A.r; } -// see: http://www.randygaul.net/2014/07/23/distance-point-to-line-segment/ +// See: https://randygaul.github.io/math/collision-detection/2014/07/01/Distance-Point-to-Line-Segment.html int c2CircletoCapsule(c2Circle A, c2Capsule B) { c2v n = c2Sub(B.b, B.a); @@ -1477,7 +1482,7 @@ static inline float c2SignedDistPointToPlane_OneDimensional(float p, float n, fl static inline float c2RayToPlane_OneDimensional(float da, float db) { if (da < 0) return 0; // Ray started behind plane. - else if (da * db >= 0) return 1.0f; // Ray starts and ends on the same of the plane. + else if (da * db > 0) return 1.0f; // Ray starts and ends on the same of the plane. else // Ray starts and ends on opposite sides of the plane (or directly on the plane). { float d = da - db; @@ -1522,10 +1527,10 @@ int c2RaytoAABB(c2Ray A, c2AABB B, c2Raycast* out) float t3 = c2RayToPlane_OneDimensional(da3, db3); // Calculate hit predicate, no branching. - int hit0 = t0 < 1.0f; - int hit1 = t1 < 1.0f; - int hit2 = t2 < 1.0f; - int hit3 = t3 < 1.0f; + int hit0 = t0 <= 1.0f; + int hit1 = t1 <= 1.0f; + int hit2 = t2 <= 1.0f; + int hit3 = t3 <= 1.0f; int hit = hit0 | hit1 | hit2 | hit3; if (hit) @@ -2225,7 +2230,7 @@ void c2PolytoPolyManifold(const c2Poly* A, const c2x* ax_ptr, const c2Poly* B, c This software is available under 2 licenses - you may choose the one you like. ------------------------------------------------------------------------------ ALTERNATIVE A - zlib license - Copyright (c) 2017 Randy Gaul http://www.randygaul.net + Copyright (c) 2023 Randy Gaul https://randygaul.github.io/ This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/libraries/cute/cute_net.h b/libraries/cute/cute_net.h index 6ec201c32..b01cfa7d6 100644 --- a/libraries/cute/cute_net.h +++ b/libraries/cute/cute_net.h @@ -3,7 +3,7 @@ Licensing information can be found at the end of the file. ------------------------------------------------------------------------------ - cute_net.h - v1.02 + cute_net.h - v1.03 To create implementation (the function definitions) #define CUTE_NET_IMPLEMENTATION @@ -105,6 +105,11 @@ * Fixed a bug where reliable sequence numbers were incremented at the wrong time, causing a desynchronization and connection drop. + 1.03 (03/27/2023) Fixed an issue where sometimes a sequence buffer would mark an + an entry as free before actually free'ing it, inevitably causing + a double free. Also added a new function cn_server_set_public_ip, + useful for testing servers behind a NAT: WARNING -- not recommended + for shipping due to compromised security!!! */ /* @@ -237,8 +242,10 @@ typedef struct cn_crypto_sign_public_t { uint8_t key[32]; } cn_crypto_sign_publi typedef struct cn_crypto_sign_secret_t { uint8_t key[64]; } cn_crypto_sign_secret_t; typedef struct cn_crypto_signature_t { uint8_t bytes[64]; } cn_crypto_signature_t; -#ifndef CN_INLINE +#ifdef __cplusplus # define CN_INLINE inline +#else +# define CN_INLINE static inline #endif //-------------------------------------------------------------------------------------------------- @@ -530,6 +537,23 @@ void cn_server_disconnect_client(cn_server_t* server, int client_index, bool not cn_result_t cn_server_send(cn_server_t* server, const void* packet, int size, int client_index, bool send_reliably); bool cn_server_is_client_connected(cn_server_t* server, int client_index); +/** + * WARNING -- For test/dev builds only! + * + * If your server runs in the cloud with a public ip (highly recommended) this function is not at all necessary. However, + * for testing purposes a lot of developers want to start out with port forwarding on their personal machine. Unfortunately + * routers nowadays will likely act as your public IP. The connect token a client uses must use the router's IP address. As + * the token is opened up by the server the server will notice it's local IP (something like 192.168.1.3) will not match the + * the server's public ip listed in the connect token, causing a disconnect. + * + * Instead you may specify the server to match against it's *local IP*, instead of the public IP. This of course compromises + * the entire security design, but it's a great way to get going before learning how to setup a proper dedicated server with + * a real public IP address. + * + * For some more info/context you can see the original GitHub issue on this topic: https://github.com/RandyGaul/cute_headers/issues/344 + */ +void cn_server_set_public_ip(cn_server_t* server, const char* address_and_port); + void cn_server_enable_network_simulator(cn_server_t* server, double latency, double jitter, double drop_chance, double duplicate_chance); float cn_server_get_packet_loss_estimate(cn_server_t* server, int client_index); float cn_server_get_rtt_estimate(cn_server_t* server, int client_index); @@ -672,7 +696,7 @@ extern "C" { #define _hydro_attr_warn_unused_result_ _hydro_attr_((warn_unused_result)) #define _hydro_attr_weak_ _hydro_attr_((weak)) -#if defined(__INTEL_COMPILER) || defined(_MSC_VER) +#if defined(__INTEL_COMPILER) || (defined(_MSC_VER) && !defined(__clang__)) #define _hydro_attr_aligned_(X) __declspec(align(X)) #elif defined(__clang__) || defined(__GNUC__) #define _hydro_attr_aligned_(X) _hydro_attr_((aligned(X))) @@ -5273,6 +5297,8 @@ struct cn_protocol_server_t bool running; uint64_t application_id; uint64_t current_time; + bool use_developer_mode_public_ip; + cn_endpoint_t developer_mode_public_ip; cn_socket_t socket; cn_protocol_packet_allocator_t* packet_allocator; cn_crypto_sign_public_t public_key; @@ -5333,7 +5359,7 @@ cn_result_t cn_init() return cn_crypto_init(); } -static CN_INLINE cn_result_t s_cn_init_check() +CN_INLINE cn_result_t s_cn_init_check() { if (!s_cn_is_init) { if (cn_is_error(cn_init())) { @@ -6499,7 +6525,7 @@ void cn_protocol_encryption_map_look_for_timeouts_or_expirations(cn_protocol_enc // ------------------------------------------------------------------------------------------------- -static CN_INLINE const char* s_protocol_client_state_str(cn_protocol_client_state_t state) +CN_INLINE const char* s_protocol_client_state_str(cn_protocol_client_state_t state) { switch (state) { @@ -6588,12 +6614,12 @@ cn_result_t cn_protocol_client_connect(cn_protocol_client_t* client, const uint8 return cn_error_success(); } -static CN_INLINE cn_endpoint_t s_protocol_server_endpoint(cn_protocol_client_t* client) +CN_INLINE cn_endpoint_t s_protocol_server_endpoint(cn_protocol_client_t* client) { return client->connect_token.endpoints[client->server_endpoint_index]; } -static CN_INLINE const char* s_protocol_packet_str(uint8_t type) +CN_INLINE const char* s_protocol_packet_str(uint8_t type) { switch (type) { @@ -7045,7 +7071,7 @@ cn_handle_t cn_handle_allocator_alloc(cn_handle_allocator_t* table, uint32_t ind return handle; } -static CN_INLINE uint32_t s_table_index(cn_handle_t handle) +CN_INLINE uint32_t s_table_index(cn_handle_t handle) { return (uint32_t)((handle & 0xFFFFFFFF00000000ULL) >> 32); } @@ -7149,12 +7175,12 @@ cn_result_t cn_protocol_server_start(cn_protocol_server_t* server, const char* a return cn_error_success(); } -static CN_INLINE int s_protocol_server_event_pull(cn_protocol_server_t* server, cn_protocol_server_event_t* event) +CN_INLINE int s_protocol_server_event_pull(cn_protocol_server_t* server, cn_protocol_server_event_t* event) { return cn_circular_buffer_pull(&server->event_queue, event, sizeof(cn_protocol_server_event_t)); } -static CN_INLINE int s_protocol_server_event_push(cn_protocol_server_t* server, cn_protocol_server_event_t* event) +CN_INLINE int s_protocol_server_event_push(cn_protocol_server_t* server, cn_protocol_server_event_t* event) { if (cn_circular_buffer_push(&server->event_queue, event, sizeof(cn_protocol_server_event_t)) < 0) { if (cn_circular_buffer_grow(&server->event_queue, server->event_queue.capacity * 2) < 0) { @@ -7341,6 +7367,9 @@ static void s_protocol_server_receive_packets(cn_protocol_server_t* server) } cn_endpoint_t server_endpoint = server->socket.endpoint; + if (server->use_developer_mode_public_ip) { + server_endpoint = server->developer_mode_public_ip; + } int found = 0; for (int i = 0; i < token.endpoint_count; ++i) { @@ -7744,7 +7773,7 @@ typedef struct cn_ack_system_t #define CN_CHECK(X) if (X) ret = -1; -#define CN_SEQUENCE_BUFFER_EMPTY (~0UL) +#define CN_SEQUENCE_BUFFER_EMPTY (0xFFFFFFFF) typedef void (cn_sequence_buffer_cleanup_entry_fn)(void* data, uint16_t sequence, void* udata, void* mem_ctx); @@ -7752,8 +7781,8 @@ void cn_sequence_buffer_remove(cn_sequence_buffer_t* buffer, uint16_t sequence, { int index = sequence % buffer->capacity; if (buffer->entry_sequence[index] != CN_SEQUENCE_BUFFER_EMPTY) { - buffer->entry_sequence[index] = CN_SEQUENCE_BUFFER_EMPTY; if (cleanup_fn) cleanup_fn(buffer->entry_data + buffer->stride * index, buffer->entry_sequence[index], buffer->udata, buffer->mem_ctx); + buffer->entry_sequence[index] = CN_SEQUENCE_BUFFER_EMPTY; } } @@ -7813,18 +7842,18 @@ static void s_sequence_buffer_remove_entries(cn_sequence_buffer_t* buffer, int s } } -static CN_INLINE int s_sequence_greater_than(uint16_t a, uint16_t b) +CN_INLINE int s_sequence_greater_than(uint16_t a, uint16_t b) { return ((a > b) && (a - b <= 32768)) | ((a < b) && (b - a > 32768)); } -static CN_INLINE int s_sequence_less_than(uint16_t a, uint16_t b) +CN_INLINE int s_sequence_less_than(uint16_t a, uint16_t b) { return s_sequence_greater_than(b, a); } -static CN_INLINE int s_sequence_is_stale(cn_sequence_buffer_t* buffer, uint16_t sequence) +CN_INLINE int s_sequence_is_stale(cn_sequence_buffer_t* buffer, uint16_t sequence) { return s_sequence_less_than(sequence, buffer->sequence - ((uint16_t)buffer->capacity)); } @@ -8309,7 +8338,7 @@ void cn_ack_system_clear_acks(cn_ack_system_t* ack_system) ack_system->acks_count = 0; } -static CN_INLINE double s_calc_packet_loss(double packet_loss, cn_sequence_buffer_t* sent_packets) +CN_INLINE double s_calc_packet_loss(double packet_loss, cn_sequence_buffer_t* sent_packets) { int packet_drop_count = 0; uint32_t base_sequence = (sent_packets->sequence - sent_packets->capacity + 1) + 0xFFFF; @@ -8333,7 +8362,7 @@ static CN_INLINE double s_calc_packet_loss(double packet_loss, cn_sequence_buffe #include -static CN_INLINE double s_calc_bandwidth(double bandwidth, cn_sequence_buffer_t* packets) +CN_INLINE double s_calc_bandwidth(double bandwidth, cn_sequence_buffer_t* packets) { int bytes_sent = 0; uint32_t base_sequence = (packets->sequence - packets->capacity + 1) + 0xFFFF; @@ -8513,7 +8542,7 @@ void cn_transport_destroy(cn_transport_t* transport) CN_FREE(transport, mem_ctx); } -static CN_INLINE int s_transport_write_header(uint8_t* buffer, int size, uint8_t prefix, uint16_t sequence, uint16_t fragment_count, uint16_t fragment_index, uint16_t fragment_size) +CN_INLINE int s_transport_write_header(uint8_t* buffer, int size, uint8_t prefix, uint16_t sequence, uint16_t fragment_count, uint16_t fragment_index, uint16_t fragment_size) { if (size < CN_TRANSPORT_HEADER_SIZE) return -1; uint8_t* buffer_start = buffer; @@ -9139,12 +9168,12 @@ void cn_server_stop(cn_server_t* server) } } -static CN_INLINE int s_server_event_pull(cn_server_t* server, cn_server_event_t* event) +CN_INLINE int s_server_event_pull(cn_server_t* server, cn_server_event_t* event) { return cn_circular_buffer_pull(&server->event_queue, event, sizeof(cn_server_event_t)); } -static CN_INLINE int s_server_event_push(cn_server_t* server, cn_server_event_t* event) +CN_INLINE int s_server_event_push(cn_server_t* server, cn_server_event_t* event) { if (cn_circular_buffer_push(&server->event_queue, event, sizeof(cn_server_event_t)) < 0) { if (cn_circular_buffer_grow(&server->event_queue, server->event_queue.capacity * 2) < 0) { @@ -9273,6 +9302,12 @@ bool cn_server_is_client_connected(cn_server_t* server, int client_index) return cn_protocol_server_is_client_connected(server->p_server, client_index); } +void cn_server_set_public_ip(cn_server_t* server, const char* address_and_port) +{ + server->p_server->use_developer_mode_public_ip = true; + cn_endpoint_init(&server->p_server->developer_mode_public_ip, address_and_port); +} + void cn_server_enable_network_simulator(cn_server_t* server, double latency, double jitter, double drop_chance, double duplicate_chance) { cn_protocol_server_enable_network_simulator(server->p_server, latency, jitter, drop_chance, duplicate_chance); @@ -12299,7 +12334,7 @@ int cn_run_tests(int which_test, bool soak) This software is available under 2 licenses - you may choose the one you like. ------------------------------------------------------------------------------ ALTERNATIVE A - zlib license - Copyright (c) 2022 Randy Gaul http://www.randygaul.net + Copyright (c) 2023 Randy Gaul https://randygaul.github.io/ This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. diff --git a/libraries/cute/cute_path.h b/libraries/cute/cute_path.h deleted file mode 100644 index c1a9d184c..000000000 --- a/libraries/cute/cute_path.h +++ /dev/null @@ -1,562 +0,0 @@ -/* - ------------------------------------------------------------------------------ - Licensing information can be found at the end of the file. - ------------------------------------------------------------------------------ - - cute_path.h - v1.01 - - To create implementation (the function definitions) - #define CUTE_PATH_IMPLEMENTATION - in *one* C/CPP file (translation unit) that includes this file - - SUMMARY: - - Collection of c-string manipulation functions for dealing with common file-path - operations. More or less a less-fully-featured replacement for Shlwapi.h path - functions on Windows. - - Performs no dynamic memory management and has no external dependencies (other than - some crt funcs). - - Revision history: - 1.0 (11/01/2017) initial release - 1.01 (11/10/2017) path_compact, path_pop bugfixes -*/ - -/* - Contributors: - sro5h 1.01 - path_compact, path_pop bugfixes -*/ - -#if !defined(CUTE_PATH_H) - -#define CUTE_PATH_MAX_PATH 1024 -#define CUTE_PATH_MAX_EXT 32 - -// Copies path to out, but not the extension. Places a nul terminator in out. -// Returns the length of the string in out, excluding the nul byte. -// Length of copied output can be up to CUTE_PATH_MAX_PATH. Can also copy the file -// extension into ext, up to CUTE_PATH_MAX_EXT. -#if !defined(__cplusplus) -int path_pop_ext(const char* path, char* out, char* ext); -#else -int path_pop_ext(const char* path, char* out = 0, char* ext = 0); -#endif - -// Copies path to out, but excludes the final file or folder from the output. -// If the final file or folder contains a period, the file or folder will -// still be appropriately popped. If the path contains only one file or folder, -// the output will contain a period representing the current directory. All -// outputs are nul terminated. -// Returns the length of the string in out, excluding the nul byte. -// Length of copied output can be up to CUTE_PATH_MAX_PATH. -// Optionally stores the popped filename in pop. pop can be NULL. -// out can also be NULL. -#if !defined(__cplusplus) -int path_pop(const char* path, char* out, char* pop); -#else -int path_pop(const char* path, char* out = 0, char* pop = 0); -#endif - -// Concatenates path_b onto the end of path_a. Will not write beyond max_buffer_length. -// Places a single '/' character between path_a and path_b. Does no other "intelligent" -// manipulation of path_a and path_b; it's a basic strcat kind of function. -void path_concat(const char* path_a, const char* path_b, char* out, int max_buffer_length); - -// Copies the name of the folder the file sits in (but not the entire path) to out. Will -// not write beyond max_buffer_length. Length of copied output can be up to CUTE_PATH_MAX_PATH. -// path contains the full path to the file in question. -// Returns 0 for inputs of "", "." or ".." as the path, 1 otherwise (success). -int path_name_of_folder_im_in(const char* path, char* out); - -// Shrinks the path to the desired length n, the out buffer will never be bigger than -// n + 1. Places three '.' between the last part of the path and the first part that -// will be shortened to fit. If the last part is too long to fit in a string of length n, -// the last part will be shortened to fit and three '.' will be added in front & back. -int path_compact(const char* path, char* out, int n); - -// Some useful (but not yet implemented) functions -/* - int path_root(const char* path, char* out); -*/ - -#define CUTE_PATH_UNIT_TESTS 1 -void path_do_unit_tests(); - -#define CUTE_PATH_H -#endif - -#ifdef CUTE_PATH_IMPLEMENTATION -#ifndef CUTE_PATH_IMPLEMENTATION_ONCE -#define CUTE_PATH_IMPLEMENTATION_ONCE - -#ifdef _WIN32 - - #if !defined(_CRT_SECURE_NO_WARNINGS) - #define _CRT_SECURE_NO_WARNINGS - #endif - -#endif - -#include // strncpy, strncat, strlen -#define CUTE_PATH_STRNCPY strncpy -#define CUTE_PATH_STRNCAT strncat -#define CUTE_PATH_STRLEN strlen - -int path_is_slash(char c) -{ - return (c == '/') | (c == '\\'); -} - -int path_pop_ext(const char* path, char* out, char* ext) -{ - if (out != NULL) - *out = '\0'; - if (ext != NULL) - *ext = '\0'; - - // skip leading dots - const char *p = path; - while (*p == '.') - ++p; - - const char *last_slash = path; - const char *last_period = NULL; - while (*p != '\0') - { - if (path_is_slash(*p)) - last_slash = p; - else if (*p == '.') - last_period = p; - ++p; - } - - if (last_period != NULL && last_period > last_slash) - { - if (ext != NULL) - CUTE_PATH_STRNCPY(ext, last_period + 1, CUTE_PATH_MAX_EXT); - } - else - { - last_period = p; - } - - int len = (int)(last_period - path); - if (len > CUTE_PATH_MAX_PATH - 1) len = CUTE_PATH_MAX_PATH - 1; - - if (out != NULL) - { - CUTE_PATH_STRNCPY(out, path, len); - out[len] = '\0'; - } - - return len; -} - -int path_pop(const char* path, char* out, char* pop) -{ - const char* original = path; - int total_len = 0; - while (*path) - { - ++total_len; - ++path; - } - - // ignore trailing slash from input path - if (path_is_slash(*(path - 1))) - { - --path; - total_len -= 1; - } - - int pop_len = 0; // length of substring to be popped - while (!path_is_slash(*--path) && pop_len != total_len) - ++pop_len; - int len = total_len - pop_len; // length to copy - - // don't ignore trailing slash if it is the first character - if (len > 1) - { - len -= 1; - } - - if (len > 0) - { - if (out) - { - CUTE_PATH_STRNCPY(out, original, len); - out[len] = 0; - } - - if (pop) - { - CUTE_PATH_STRNCPY(pop, path + 1, pop_len); - pop[pop_len] = 0; - } - - return len; - } - - else - { - if (out) - { - out[0] = '.'; - out[1] = 0; - } - if (pop) *pop = 0; - return 1; - } -} - -static int path_strncpy(char* dst, const char* src, int n, int max) -{ - int c; - - do - { - if (n >= max - 1) - { - dst[max - 1] = 0; - break; - } - c = *src++; - dst[n] = c; - ++n; - } while (c); - - return n; -} - -void path_concat(const char* path_a, const char* path_b, char* out, int max_buffer_length) -{ - int n = path_strncpy(out, path_a, 0, max_buffer_length); - n = path_strncpy(out, "/", n - 1, max_buffer_length); - path_strncpy(out, path_b, n - 1, max_buffer_length); -} - -int path_name_of_folder_im_in(const char* path, char* out) -{ - // return failure for empty strings and "." or ".." - if (!*path || (*path == '.' && CUTE_PATH_STRLEN(path) < 3)) return 0; - int len = path_pop(path, out, NULL); - int has_slash = 0; - for (int i = 0; out[i]; ++i) - { - if (path_is_slash(out[i])) - { - has_slash = 1; - break; - } - } - - if (has_slash) - { - int n = path_pop(out, NULL, NULL) + 1; - len -= n; - CUTE_PATH_STRNCPY(out, path + n, len); - } - - else CUTE_PATH_STRNCPY(out, path, len); - out[len] = 0; - return 1; -} - -int path_compact(const char* path, char* out, int n) -{ - if (n <= 6) return 0; - - const char* sep = "..."; - const int seplen = (int)strlen(sep); - - int pathlen = (int)strlen(path); - out[0] = 0; - - if (pathlen <= n) - { - CUTE_PATH_STRNCPY(out, path, pathlen); - out[pathlen] = 0; - return pathlen; - } - - // Find last path separator - // Ignores the last character as it could be a path separator - int i = pathlen - 1; - do - { - --i; - } while (!path_is_slash(path[i]) && i > 0); - - const char* back = path + i; - int backlen = (int)strlen(back); - - // No path separator was found or the first character was one - if (pathlen == backlen) - { - CUTE_PATH_STRNCPY(out, path, n - seplen); - out[n - seplen] = 0; - CUTE_PATH_STRNCAT(out, sep, seplen + 1); - return n; - } - - // Last path part with separators in front equals n - if (backlen == n - seplen) - { - CUTE_PATH_STRNCPY(out, sep, seplen + 1); - CUTE_PATH_STRNCAT(out, back, backlen); - return n; - } - - // Last path part with separators in front is too long - if (backlen > n - seplen) - { - CUTE_PATH_STRNCPY(out, sep, seplen + 1); - CUTE_PATH_STRNCAT(out, back, n - (2 * seplen)); - CUTE_PATH_STRNCAT(out, sep, seplen); - return n; - } - - int remaining = n - backlen - seplen; - - CUTE_PATH_STRNCPY(out, path, remaining); - out[remaining] = 0; - CUTE_PATH_STRNCAT(out, sep, seplen); - CUTE_PATH_STRNCAT(out, back, backlen); - - return n; -} - -#if CUTE_PATH_UNIT_TESTS - - #include - - #define CUTE_PATH_STRCMP strcmp - #define CUTE_PATH_EXPECT(X) do { if (!(X)) printf("Failed cute_path.h unit test at line %d of file %s.\n", __LINE__, __FILE__); } while (0) - - void path_do_unit_tests() - { - char out[CUTE_PATH_MAX_PATH]; - char pop[CUTE_PATH_MAX_PATH]; - char ext[CUTE_PATH_MAX_PATH]; - int n; - - const char* path = "../root/file.ext"; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "../root/file")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "ext")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "../root")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "file.ext")); - - path = "../root/file"; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "../root/file")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "../root")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "file")); - - path = "../root/"; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "../root/")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "..")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "root")); - - path = "../root"; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "../root")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "..")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "root")); - - path = "/file"; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "/file")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "/")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "file")); - - path = "../"; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "../")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, ".")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "")); - - path = ".."; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "..")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, ".")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "")); - - path = "."; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, ".")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, ".")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "")); - - path = ""; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, ".")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "")); - - path = "../../file.ext"; - path_pop_ext(path, out, ext); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "../../file")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(ext, "ext")); - - path_pop(path, out, pop); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "../..")); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(pop, "file.ext")); - - path = "asdf/file.ext"; - path_name_of_folder_im_in(path, out); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "asdf")); - - path = "asdf/lkjh/file.ext"; - path_name_of_folder_im_in(path, out); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "lkjh")); - - path = "poiu/asdf/lkjh/file.ext"; - path_name_of_folder_im_in(path, out); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "lkjh")); - - path = "poiu/asdf/lkjhqwer/file.ext"; - path_name_of_folder_im_in(path, out); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "lkjhqwer")); - - path = "../file.ext"; - path_name_of_folder_im_in(path, out); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "..")); - - path = "./file.ext"; - path_name_of_folder_im_in(path, out); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, ".")); - - path = ".."; - CUTE_PATH_EXPECT(!path_name_of_folder_im_in(path, out)); - - path = "."; - CUTE_PATH_EXPECT(!path_name_of_folder_im_in(path, out)); - - path = ""; - CUTE_PATH_EXPECT(!path_name_of_folder_im_in(path, out)); - - const char* path_a = "asdf"; - const char* path_b = "qwerzxcv"; - path_concat(path_a, path_b, out, CUTE_PATH_MAX_PATH); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "asdf/qwerzxcv")); - - path_a = "path/owoasf.as.f.q.e.a"; - path_b = ".."; - path_concat(path_a, path_b, out, CUTE_PATH_MAX_PATH); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "path/owoasf.as.f.q.e.a/..")); - - path_a = "a/b/c"; - path_b = "d/e/f/g/h/i"; - path_concat(path_a, path_b, out, CUTE_PATH_MAX_PATH); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "a/b/c/d/e/f/g/h/i")); - - path = "/path/to/file.vim"; - n = path_compact(path, out, 17); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "/path/to/file.vim")); - CUTE_PATH_EXPECT(n == CUTE_PATH_STRLEN(out)); - - path = "/path/to/file.vim"; - n = path_compact(path, out, 16); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "/pat.../file.vim")); - CUTE_PATH_EXPECT(n == CUTE_PATH_STRLEN(out)); - - path = "/path/to/file.vim"; - n = path_compact(path, out, 12); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, ".../file.vim")); - CUTE_PATH_EXPECT(n == CUTE_PATH_STRLEN(out)); - - path = "/path/to/file.vim"; - n = path_compact(path, out, 11); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, ".../file...")); - CUTE_PATH_EXPECT(n == CUTE_PATH_STRLEN(out)); - - path = "longfile.vim"; - n = path_compact(path, out, 12); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "longfile.vim")); - CUTE_PATH_EXPECT(n == CUTE_PATH_STRLEN(out)); - - path = "longfile.vim"; - n = path_compact(path, out, 11); - CUTE_PATH_EXPECT(!CUTE_PATH_STRCMP(out, "longfile...")); - CUTE_PATH_EXPECT(n == CUTE_PATH_STRLEN(out)); - } - -#else - - void path_do_unit_tests() - { - } - -#endif // CUTE_PATH_UNIT_TESTS - -#endif // CUTE_PATH_IMPLEMENTATION_ONCE -#endif // CUTE_PATH_IMPLEMENTATION - -/* - ------------------------------------------------------------------------------ - This software is available under 2 licenses - you may choose the one you like. - ------------------------------------------------------------------------------ - ALTERNATIVE A - zlib license - Copyright (c) 2017 Randy Gaul http://www.randygaul.net - This software is provided 'as-is', without any express or implied warranty. - In no event will the authors be held liable for any damages arising from - the use of this software. - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not - be misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - ------------------------------------------------------------------------------ - ALTERNATIVE B - Public Domain (www.unlicense.org) - This is free and unencumbered software released into the public domain. - Anyone is free to copy, modify, publish, use, compile, sell, or distribute this - software, either in source code form or as a compiled binary, for any purpose, - commercial or non-commercial, and by any means. - In jurisdictions that recognize copyright laws, the author or authors of this - software dedicate any and all copyright interest in the software to the public - domain. We make this dedication for the benefit of the public at large and to - the detriment of our heirs and successors. We intend this dedication to be an - overt act of relinquishment in perpetuity of all present and future rights to - this software under copyright law. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------------------------------------------------------------------------------ -*/ diff --git a/libraries/cute/cute_png.h b/libraries/cute/cute_png.h index d428743b3..16926cd1a 100644 --- a/libraries/cute/cute_png.h +++ b/libraries/cute/cute_png.h @@ -3,7 +3,7 @@ Licensing information can be found at the end of the file. ------------------------------------------------------------------------------ - cute_png.h - v1.04 + cute_png.h - v1.05 To create implementation (the function definitions) #define CUTE_PNG_IMPLEMENTATION @@ -24,6 +24,7 @@ 1.03 (11/12/2017) construct atlas in memory 1.04 (08/23/2018) various bug fixes for filter and word decoder added `cp_load_blank` + 1.05 (11/10/2022) added `cp_save_png_to_memory` EXAMPLES: @@ -65,6 +66,35 @@ // this function requires knowledge of the un-compressed size // does *not* do any internal realloc! Will return errors if an // attempt to overwrite the out buffer is made + + CUSTOMIZATION + + There are various macros in this header you can customize by defining them before + including cute_png.h. Simply define one to override the default behavior. + + CUTE_PNG_ALLOCA + CUTE_PNG_ALLOC + CUTE_PNG_FREE + CUTE_PNG_CALLOC + CUTE_PNG_REALLOC + CUTE_PNG_MEMCPY + CUTE_PNG_MEMCMP + CUTE_PNG_MEMSET + CUTE_PNG_ASSERT + CUTE_PNG_FPRINTF + CUTE_PNG_SEEK_SET + CUTE_PNG_SEEK_END + CUTE_PNG_FILE + CUTE_PNG_FOPEN + CUTE_PNG_FSEEK + CUTE_PNG_FREAD + CUTE_PNG_FTELL + CUTE_PNG_FWRITE + CUTE_PNG_FCLOSE + CUTE_PNG_FERROR + CUTE_PNG_ATLAS_MUST_FIT + CUTE_PNG_ATLAS_FLIP_Y_AXIS_FOR_UV + CUTE_PNG_ATLAS_EMPTY_COLOR */ /* @@ -77,16 +107,22 @@ #if !defined(CUTE_PNG_H) #ifdef _WIN32 - #if !defined(_CRT_SECURE_NO_WARNINGS) #define _CRT_SECURE_NO_WARNINGS #endif - #endif -#define CUTE_PNG_ATLAS_MUST_FIT 1 // returns error from cp_make_atlas if *any* input image does not fit -#define CUTE_PNG_ATLAS_FLIP_Y_AXIS_FOR_UV 1 // flips output uv coordinate's y. Can be useful to "flip image on load" -#define CUTE_PNG_ATLAS_EMPTY_COLOR 0x000000FF // the fill color for empty areas in a texture atlas (RGBA) +#ifndef CUTE_PNG_ATLAS_MUST_FIT + #define CUTE_PNG_ATLAS_MUST_FIT 1 // returns error from cp_make_atlas if *any* input image does not fit +#endif // CUTE_PNG_ATLAS_MUST_FIT + +#ifndef CUTE_PNG_ATLAS_FLIP_Y_AXIS_FOR_UV + #define CUTE_PNG_ATLAS_FLIP_Y_AXIS_FOR_UV 1 // flips output uv coordinate's y. Can be useful to "flip image on load" +#endif // CUTE_PNG_ATLAS_FLIP_Y_AXIS_FOR_UV + +#ifndef CUTE_PNG_ATLAS_EMPTY_COLOR + #define CUTE_PNG_ATLAS_EMPTY_COLOR 0x000000FF // the fill color for empty areas in a texture atlas (RGBA) +#endif // CUTE_PNG_ATLAS_EMPTY_COLOR #include #include @@ -103,6 +139,18 @@ extern const char* cp_error_reason; int cp_inflate(void* in, int in_bytes, void* out, int out_bytes); int cp_save_png(const char* file_name, const cp_image_t* img); +typedef struct cp_saved_png_t +{ + int size; // Size of the `data` buffer. + void* data; // Pointer to the saved png in memory. + // NULL if something went wrong. + // Call CUTE_PNG_FREE on `data` when done. +} cp_saved_png_t; + +// Saves a png file to memory. +// Call CUTE_PNG_FREE on .data when done. +cp_saved_png_t cp_save_png_to_memory(const cp_image_t* img); + // Constructs an atlas image in-memory. The atlas pixels are stored in the returned image. free the pixels // when done with them. The user must provide an array of cp_atlas_image_t for the `imgs` param. `imgs` holds // information about uv coordinates for an associated image in the `pngs` array. Output image has NULL @@ -183,45 +231,104 @@ struct cp_atlas_image_t #define CUTE_PNG_ALLOCA alloca #ifdef _WIN32 - #include // alloca - #else - #include // alloca + #include + #elif defined(__linux__) + #include #endif #endif #if !defined(CUTE_PNG_ALLOC) - #include // malloc, free, calloc + #include #define CUTE_PNG_ALLOC malloc +#endif + +#if !defined(CUTE_PNG_FREE) + #include #define CUTE_PNG_FREE free +#endif + +#if !defined(CUTE_PNG_CALLOC) + #include #define CUTE_PNG_CALLOC calloc #endif +#if !defined(CUTE_PNG_REALLOC) + #include + #define CUTE_PNG_REALLOC realloc +#endif + #if !defined(CUTE_PNG_MEMCPY) - #include // memcpy + #include #define CUTE_PNG_MEMCPY memcpy #endif +#if !defined(CUTE_PNG_MEMCMP) + #include + #define CUTE_PNG_MEMCMP memcmp +#endif + #if !defined(CUTE_PNG_MEMSET) - #include // memset + #include #define CUTE_PNG_MEMSET memset #endif #if !defined(CUTE_PNG_ASSERT) - #include // assert + #include #define CUTE_PNG_ASSERT assert #endif -#if !defined(CUTE_PNG_STDIO) - #include // fopen, fclose, etc. - #define CUTE_PNG_STDIO +#if !defined(CUTE_PNG_FPRINTF) + #include + #define CUTE_PNG_FPRINTF fprintf +#endif + +#if !defined(CUTE_PNG_SEEK_SET) + #include #define CUTE_PNG_SEEK_SET SEEK_SET +#endif + +#if !defined(CUTE_PNG_SEEK_END) + #include #define CUTE_PNG_SEEK_END SEEK_END +#endif + +#if !defined(CUTE_PNG_FILE) + #include #define CUTE_PNG_FILE FILE +#endif + +#if !defined(CUTE_PNG_FOPEN) + #include #define CUTE_PNG_FOPEN fopen +#endif + +#if !defined(CUTE_PNG_FSEEK) + #include #define CUTE_PNG_FSEEK fseek +#endif + +#if !defined(CUTE_PNG_FREAD) + #include #define CUTE_PNG_FREAD fread +#endif + +#if !defined(CUTE_PNG_FTELL) + #include #define CUTE_PNG_FTELL ftell +#endif + +#if !defined(CUTE_PNG_FWRITE) + #include + #define CUTE_PNG_FWRITE fwrite +#endif + +#if !defined(CUTE_PNG_FCLOSE) + #include #define CUTE_PNG_FCLOSE fclose +#endif + +#if !defined(CUTE_PNG_FERROR) + #include #define CUTE_PNG_FERROR ferror #endif @@ -619,7 +726,9 @@ typedef struct cp_save_png_data_t uint32_t bits; uint32_t prev; uint32_t runlen; - CUTE_PNG_FILE *fp; + int buflen; + int bufcap; + char* buffer; } cp_save_png_data_t; uint32_t CP_CRC_TABLE[] = { @@ -629,7 +738,12 @@ uint32_t CP_CRC_TABLE[] = { static void cp_put8(cp_save_png_data_t* s, uint32_t a) { - fputc(a, s->fp); + if (s->buflen >= s->bufcap) + { + s->bufcap *= 2; + s->buffer = (char*)CUTE_PNG_REALLOC(s->buffer, s->bufcap); + } + s->buffer[s->buflen++] = a; s->crc = (s->crc >> 4) ^ CP_CRC_TABLE[(s->crc & 15) ^ (a & 15)]; s->crc = (s->crc >> 4) ^ CP_CRC_TABLE[(s->crc & 15) ^ (a >> 4)]; } @@ -677,10 +791,10 @@ static void cp_begin_chunk(cp_save_png_data_t* s, const char* id, uint32_t len) { cp_put32(s, len); s->crc = 0xFFFFFFFF; - cp_put8(s, id[0]); - cp_put8(s, id[1]); - cp_put8(s, id[2]); - cp_put8(s, id[3]); + cp_put8(s, (unsigned char)id[0]); + cp_put8(s, (unsigned char)id[1]); + cp_put8(s, (unsigned char)id[2]); + cp_put8(s, (unsigned char)id[3]); } static void cp_encode_literal(cp_save_png_data_t* s, uint32_t v) @@ -732,7 +846,10 @@ static void cp_encode_byte(cp_save_png_data_t *s, uint8_t v) static void cp_save_header(cp_save_png_data_t* s, cp_image_t* img) { - fwrite("\211PNG\r\n\032\n", 8, 1, s->fp); + const unsigned char* hdr = (const unsigned char*)"\211PNG\r\n\032\n"; + for (int i = 0; i < 8; ++i) { + cp_put8(s, *hdr++); + } cp_begin_chunk(s, "IHDR", 13); cp_put32(s, img->w); cp_put32(s, img->h); @@ -744,7 +861,7 @@ static void cp_save_header(cp_save_png_data_t* s, cp_image_t* img) cp_put32(s, ~s->crc); } -static long cp_save_data(cp_save_png_data_t* s, cp_image_t* img, long dataPos) +static void cp_save_data(cp_save_png_data_t* s, cp_image_t* img, long dataPos, long* dataSize) { cp_begin_chunk(s, "IDAT", 0); cp_put8(s, 0x08); // zlib compression method @@ -771,40 +888,52 @@ static long cp_save_data(cp_save_png_data_t* s, cp_image_t* img, long dataPos) cp_encode_literal(s, 256); // terminator while (s->bits != 0x80) cp_put_bits(s, 0, 1); cp_put32(s, s->adler); - long dataSize = (CUTE_PNG_FTELL(s->fp) - dataPos) - 8; + *dataSize = (s->buflen - dataPos) - 8; cp_put32(s, ~s->crc); - - return dataSize; } -int cp_save_png(const char* file_name, const cp_image_t* img) +cp_saved_png_t cp_save_png_to_memory(const cp_image_t* img) { - cp_save_png_data_t s; - long dataPos, dataSize, err; - - CUTE_PNG_FILE* fp = CUTE_PNG_FOPEN(file_name, "wb"); - if (!fp) return 1; + cp_saved_png_t result = { 0 }; + cp_save_png_data_t s = { 0 }; + long dataPos, dataSize, fileSize; + if (!img) return result; - s.fp = fp; s.adler = 1; s.bits = 0x80; s.prev = 0xFFFF; - s.runlen = 0; + s.bufcap = 1024; + s.buffer = (char*)CUTE_PNG_ALLOC(1024); cp_save_header(&s, (cp_image_t*)img); - dataPos = CUTE_PNG_FTELL(s.fp); - dataSize = cp_save_data(&s, (cp_image_t*)img, dataPos); + dataPos = s.buflen; + cp_save_data(&s, (cp_image_t*)img, dataPos, &dataSize); // End chunk. cp_begin_chunk(&s, "IEND", 0); cp_put32(&s, ~s.crc); // Write back payload size. - CUTE_PNG_FSEEK(fp, dataPos, CUTE_PNG_SEEK_SET); + fileSize = s.buflen; + s.buflen = dataPos; cp_put32(&s, dataSize); + result.size = fileSize; + result.data = s.buffer; + return result; +} + +int cp_save_png(const char* file_name, const cp_image_t* img) +{ + cp_saved_png_t s; + long err; + CUTE_PNG_FILE* fp = CUTE_PNG_FOPEN(file_name, "wb"); + if (!fp) return 1; + s = cp_save_png_to_memory(img); + CUTE_PNG_FWRITE(s.data, s.size, 1, fp); err = CUTE_PNG_FERROR(fp); CUTE_PNG_FCLOSE(fp); + CUTE_PNG_FREE(s.data); return !err; } @@ -824,7 +953,7 @@ static const uint8_t* cp_chunk(cp_raw_png_t* png, const char* chunk, uint32_t mi uint32_t len = cp_make32(png->p); const uint8_t* start = png->p; - if (!memcmp(start + 4, chunk, 4) && len >= minlen) + if (!CUTE_PNG_MEMCMP(start + 4, chunk, 4) && len >= minlen) { int offset = len + 12; @@ -847,7 +976,7 @@ static const uint8_t* cp_find(cp_raw_png_t* png, const char* chunk, uint32_t min start = png->p; png->p += len + 12; - if (!memcmp(start+4, chunk, 4) && len >= minlen && png->p <= png->end) + if (!CUTE_PNG_MEMCMP(start+4, chunk, 4) && len >= minlen && png->p <= png->end) return start + 8; } @@ -967,7 +1096,7 @@ cp_image_t cp_load_png_mem(const void* png_data, int png_length) png.p = (uint8_t*)png_data; png.end = (uint8_t*)png_data + png_length; - CUTE_PNG_CHECK(!memcmp(png.p, sig, 8), "incorrect file signature (is this a png file?)"); + CUTE_PNG_CHECK(!CUTE_PNG_MEMCMP(png.p, sig, 8), "incorrect file signature (is this a png file?)"); png.p += 8; ihdr = cp_chunk(&png, "IHDR", 13); @@ -991,6 +1120,7 @@ cp_image_t cp_load_png_mem(const void* png_data, int png_length) h = cp_make32(ihdr + 4); CUTE_PNG_CHECK(w >= 1, "invalid IHDR chunk found, image width was less than 1"); CUTE_PNG_CHECK(h >= 1, "invalid IHDR chunk found, image height was less than 1"); + CUTE_PNG_CHECK((int64_t) w * h * sizeof(cp_pixel_t) < INT_MAX, "image too large"); pix_bytes = w * h * sizeof(cp_pixel_t); img.w = w - 1; img.h = h; @@ -1127,7 +1257,7 @@ void cp_load_png_wh(const void* png_data, int png_length, int* w_out, int* h_out if (w_out) *w_out = 0; if (h_out) *h_out = 0; - CUTE_PNG_CHECK(!memcmp(png.p, sig, 8), "incorrect file signature (is this a png file?)"); + CUTE_PNG_CHECK(!CUTE_PNG_MEMCMP(png.p, sig, 8), "incorrect file signature (is this a png file?)"); png.p += 8; ihdr = cp_chunk(&png, "IHDR", 13); @@ -1195,7 +1325,7 @@ cp_indexed_image_t cp_load_indexed_png_mem(const void *png_data, int png_length) png.p = (uint8_t*)png_data; png.end = (uint8_t*)png_data + png_length; - CUTE_PNG_CHECK(!memcmp(png.p, sig, 8), "incorrect file signature (is this a png file?)"); + CUTE_PNG_CHECK(!CUTE_PNG_MEMCMP(png.p, sig, 8), "incorrect file signature (is this a png file?)"); png.p += 8; ihdr = cp_chunk(&png, "IHDR", 13); @@ -1209,6 +1339,7 @@ cp_indexed_image_t cp_load_indexed_png_mem(const void *png_data, int png_length) // +1 for filter byte (which is dumb! just stick this at file header...) w = cp_make32(ihdr) + 1; h = cp_make32(ihdr + 4); + CUTE_PNG_CHECK((int64_t) w * h * sizeof(uint8_t) < INT_MAX, "image too large"); pix_bytes = w * h * sizeof(uint8_t); img.w = w - 1; img.h = h; @@ -1518,7 +1649,7 @@ cp_image_t cp_make_atlas(int atlas_width, int atlas_height, const cp_image_t* pn int new_capacity = atlas_node_capacity * 2; cp_atlas_node_t* new_nodes = (cp_atlas_node_t*)CUTE_PNG_ALLOC(sizeof(cp_atlas_node_t) * new_capacity); CUTE_PNG_CHECK(new_nodes, "out of mem"); - memcpy(new_nodes, nodes, sizeof(cp_atlas_node_t) * sp); + CUTE_PNG_MEMCPY(new_nodes, nodes, sizeof(cp_atlas_node_t) * sp); CUTE_PNG_FREE(nodes); // best_fit became a dangling pointer, so relocate it best_fit = new_nodes + (best_fit - nodes); @@ -1646,7 +1777,7 @@ int cp_default_save_atlas(const char* out_path_image, const char* out_path_atlas CUTE_PNG_FILE* fp = CUTE_PNG_FOPEN(out_path_atlas_txt, "wt"); CUTE_PNG_CHECK(fp, "unable to open out_path_atlas_txt in cp_default_save_atlas"); - fprintf(fp, "%s\n%d\n\n", out_path_image, img_count); + CUTE_PNG_FPRINTF(fp, "%s\n%d\n\n", out_path_image, img_count); for (int i = 0; i < img_count; ++i) { @@ -1662,8 +1793,8 @@ int cp_default_save_atlas(const char* out_path_image, const char* out_path_atlas float max_x = image->maxx; float max_y = image->maxy; - if (name) fprintf(fp, "{ \"%s\", w = %d, h = %d, u = { %.10f, %.10f }, v = { %.10f, %.10f } }\n", name, width, height, min_x, min_y, max_x, max_y); - else fprintf(fp, "{ w = %d, h = %d, u = { %.10f, %.10f }, v = { %.10f, %.10f } }\n", width, height, min_x, min_y, max_x, max_y); + if (name) CUTE_PNG_FPRINTF(fp, "{ \"%s\", w = %d, h = %d, u = { %.10f, %.10f }, v = { %.10f, %.10f } }\n", name, width, height, min_x, min_y, max_x, max_y); + else CUTE_PNG_FPRINTF(fp, "{ w = %d, h = %d, u = { %.10f, %.10f }, v = { %.10f, %.10f } }\n", width, height, min_x, min_y, max_x, max_y); } } diff --git a/roadmap.md b/roadmap.md new file mode 100644 index 000000000..7a9bda31b --- /dev/null +++ b/roadmap.md @@ -0,0 +1,10 @@ +Planned work, in priority order +- Input binding abstraction + +Potential work, in no order +- Hardening and stable release of net code +- Broadphase abstraction for collision +- Sound FX priority +- N music tracks +- Multi-screen support (SDL2 hookins), specify screen upon startup +- Lua bindings diff --git a/src/cute_draw.cpp b/src/cute_draw.cpp index be9d8ee94..64f103cf6 100644 --- a/src/cute_draw.cpp +++ b/src/cute_draw.cpp @@ -695,10 +695,6 @@ void cf_draw_circle_fill2(CF_V2 position, float radius) s_draw_circle(position, 0, radius, true); } -void cf_draw_arc(CF_V2 p, CF_V2 center_of_arc, float range, int iters, float thickness) -{ -} - static CF_INLINE void s_bounding_box_of_capsule(v2 a, v2 b, float radius, float stroke, v2 out[4]) { float aaf = draw->aaf; diff --git a/src/cute_handle_table.cpp b/src/cute_handle_table.cpp index 33c4fcde5..fb04960c1 100644 --- a/src/cute_handle_table.cpp +++ b/src/cute_handle_table.cpp @@ -61,7 +61,7 @@ CF_HandleTable* cf_make_handle_allocator(int initial_capacity) CF_PLACEMENT_NEW(table) CF_HandleTable(); if (initial_capacity) { - table->m_handles.ensure_capacity(initial_capacity); + table->m_handles.ensure_count(initial_capacity); int last_index = table->m_handles.capacity() - 1; s_add_elements_to_freelist(table, 0, last_index); } @@ -82,7 +82,7 @@ CF_Handle cf_handle_allocator_alloc(CF_HandleTable* table, uint32_t index, uint1 if (freelist_index == UINT32_MAX) { int first_index = table->m_handles.capacity(); if (!first_index) first_index = 1; - table->m_handles.ensure_capacity(first_index * 2); + table->m_handles.ensure_count(first_index * 2); int last_index = table->m_handles.capacity() - 1; s_add_elements_to_freelist(table, first_index, last_index); freelist_index = table->m_freelist; diff --git a/src/cute_version.cpp b/src/cute_version.cpp index eba2fee26..af67aea5f 100644 --- a/src/cute_version.cpp +++ b/src/cute_version.cpp @@ -10,5 +10,5 @@ const char* cf_version_string_linked() { - return "Cute Framework Version 0.0"; + return "Cute Framework Version 1.0"; } diff --git a/todo.txt b/todo.txt index 3fe2fd0b2..23b589bd1 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,2 @@ -resync all cute_headers set cute_version.h -ECS docs in code make cute snake work again -implement draw arc -ecs handle bugfix