diff options
author | nathansmithsmith <thenathansmithsmith@gmail.com> | 2023-07-07 23:10:23 -0600 |
---|---|---|
committer | nathansmithsmith <thenathansmithsmith@gmail.com> | 2023-07-07 23:10:23 -0600 |
commit | e5268813dcbdc0d90a081b2223ebc21749038635 (patch) | |
tree | 7c917996749e4123fb1fe49ddd1ed3b8f7e92334 /src | |
parent | a90e1987de75cfecc2693952625af8cce507ae95 (diff) |
Better world
Diffstat (limited to 'src')
-rw-r--r-- | src/assets.c | 39 | ||||
-rw-r--r-- | src/assets.h | 37 | ||||
-rw-r--r-- | src/entities/antifaShip.c | 19 | ||||
-rw-r--r-- | src/entities/antifaShip.h | 2 | ||||
-rw-r--r-- | src/entities/soldato.c | 18 | ||||
-rw-r--r-- | src/entities/soldato.h | 12 | ||||
-rw-r--r-- | src/entity.c | 16 | ||||
-rw-r--r-- | src/entity.h | 12 | ||||
-rw-r--r-- | src/game.c | 68 | ||||
-rw-r--r-- | src/game.h | 6 | ||||
-rw-r--r-- | src/gameCommon.h | 7 | ||||
-rw-r--r-- | src/gameScreen.c | 8 | ||||
-rw-r--r-- | src/mainMenu.c | 38 | ||||
-rw-r--r-- | src/mainMenu.h | 6 | ||||
-rw-r--r-- | src/playerCamera.c | 8 | ||||
-rw-r--r-- | src/util.h | 7 | ||||
-rw-r--r-- | src/world.c | 250 | ||||
-rw-r--r-- | src/world.h | 31 |
18 files changed, 539 insertions, 45 deletions
diff --git a/src/assets.c b/src/assets.c new file mode 100644 index 0000000..1f0c95b --- /dev/null +++ b/src/assets.c @@ -0,0 +1,39 @@ +#include "assets.h" + +const char textureAssetPaths[TEXTURE_ASSET_COUNT][ASSET_PATH_MAX] = { + "/home/nathan/Documents/KillaFacsista/assets/icon.png", + "/home/nathan/Documents/KillaFacsista/assets/icon128.png", + "/home/nathan/Documents/KillaFacsista/assets/icon64.png" +}; + +const char modelAssetPaths[MODEL_ASSET_COUNT][ASSET_PATH_MAX] = { + "/home/nathan/Documents/KillaFacsista/assets/antifaShip.obj" +}; + +void LoadAssets(Assets * assets) { + int i; + + // Textures. + for (i = 0; i < TEXTURE_ASSET_COUNT; ++i) + assets->textures[i] = LoadTexture(textureAssetPaths[i]); + + // Models. + for (i = 0; i < MODEL_ASSET_COUNT; ++i) + assets->models[i] = LoadModel(modelAssetPaths[i]); + + TraceLog(LOG_INFO, "Assets loaded"); +} + +void unloadAssets(Assets * assets) { + int i; + + // Textures. + for (i = 0; i < TEXTURE_ASSET_COUNT; ++i) + UnloadTexture(assets->textures[i]); + + // Models. + for (i = 0; i < MODEL_ASSET_COUNT; ++i) + UnloadModel(assets->models[i]); + + TraceLog(LOG_INFO, "Assets unloaded"); +} diff --git a/src/assets.h b/src/assets.h new file mode 100644 index 0000000..f28ddb8 --- /dev/null +++ b/src/assets.h @@ -0,0 +1,37 @@ +#include "gameCommon.h" + +#ifndef ASSETS_H +#define ASSETS_H + +#define ASSET_PATH_MAX 255 + +#define TEXTURE_ASSET_COUNT 3 +#define MODEL_ASSET_COUNT 1 + +// Paths to assets. +extern const char textureAssetPaths[TEXTURE_ASSET_COUNT][ASSET_PATH_MAX]; +extern const char modelAssetPaths[MODEL_ASSET_COUNT][ASSET_PATH_MAX]; + +typedef int32_t AssetId; + +// Texture asset ids. +enum { + ICON_ASSET, + ICON128_ASSET, + ICON64_ASSET +}; + +// Model asset ids. +enum { + ANTIFA_SHIP_ASSET +}; + +typedef struct Assets { + Texture2D textures[TEXTURE_ASSET_COUNT]; + Model models[MODEL_ASSET_COUNT]; +} Assets; + +void LoadAssets(Assets * assets); +void unloadAssets(Assets * assets); + +#endif diff --git a/src/entities/antifaShip.c b/src/entities/antifaShip.c index 1944053..f43a7df 100644 --- a/src/entities/antifaShip.c +++ b/src/entities/antifaShip.c @@ -1,28 +1,21 @@ #include "antifaShip.h" -#include <raylib.h> +#include "game.h" -void initAntifaShip(Entity * entity) { - entity->model = LoadModel("/home/nathan/Documents/KillaFacsista/assets/antifaShip.obj"); +void initAntifaShip(Entity * entity, Game * game) { + entity->model = &game->assets.models[ANTIFA_SHIP_ASSET]; entity->useAcceleration = true; entity->acceleration = (EntityAcceleration){ .speedUp = 30.0, .speedDown = 15, - .rotationUp = (Vector3){0.6, 0.6, 0.6}, - .rotationDown = (Vector3){0.6, 0.6, 0.6} + .rotation = (Vector3){0.7, 0.7, 0.7} }; } void closeAntifaShip(Entity * entity) { - UnloadModel(entity->model); } void updateAntifaShip(Game * game, Entity * entity, EntityId id) { -} - -void drawAntifaShip(Game * game, Entity * entity, EntityId id) { - entityDraw(entity); - Vector3 stick = (Vector3){ GetGamepadAxisMovement(0, 1), -GetGamepadAxisMovement(0, 0), @@ -33,3 +26,7 @@ void drawAntifaShip(Game * game, Entity * entity, EntityId id) { entityJoystickControl(entity, stick, fabs(GetGamepadAxisMovement(0, 3) * 300.0)); } + +void drawAntifaShip(Game * game, Entity * entity, EntityId id) { + entityDraw(entity); +} diff --git a/src/entities/antifaShip.h b/src/entities/antifaShip.h index 15e9009..a1b97d2 100644 --- a/src/entities/antifaShip.h +++ b/src/entities/antifaShip.h @@ -4,7 +4,7 @@ #ifndef ANTIFA_SHIP_H #define ANTIFA_SHIP_H -void initAntifaShip(Entity * entity); +void initAntifaShip(Entity * entity, Game * game); void closeAntifaShip(Entity * entity); void updateAntifaShip(Game * game, Entity * entity, EntityId id); void drawAntifaShip(Game * game, Entity * entity, EntityId id); diff --git a/src/entities/soldato.c b/src/entities/soldato.c new file mode 100644 index 0000000..c1903d4 --- /dev/null +++ b/src/entities/soldato.c @@ -0,0 +1,18 @@ +#include "soldato.h" +#include "game.h" + +void initSoldato(Entity * entity, Game * game) { + entity->model = &game->assets.models[ANTIFA_SHIP_ASSET]; + entity->velocity.angularVelocity = (AxisAngle){(Vector3){1.0, 1.0, 1.0}, 1.0}; +} + +void closeSoldato(Entity * entity) { +} + +void updateSoldato(Game * game, Entity * entity, EntityId id) { + entityUpdateRotation(entity); +} + +void drawSoldato(Game * game, Entity * entity, EntityId id) { + entityDraw(entity); +} diff --git a/src/entities/soldato.h b/src/entities/soldato.h new file mode 100644 index 0000000..4069b26 --- /dev/null +++ b/src/entities/soldato.h @@ -0,0 +1,12 @@ +#include "gameCommon.h" +#include "entity.h" + +#ifndef SOLDATO_H +#define SOLDATO_H + +void initSoldato(Entity * entity, Game * game); +void closeSoldato(Entity * entity); +void updateSoldato(Game * game, Entity * entity, EntityId id); +void drawSoldato(Game * game, Entity * entity, EntityId id); + +#endif diff --git a/src/entity.c b/src/entity.c index c88c767..f4066b5 100644 --- a/src/entity.c +++ b/src/entity.c @@ -1,9 +1,11 @@ #include "entity.h" #include "entities/antifaShip.h" +#include "entities/soldato.h" // This fucker is used for creating entities. const EntityTypeInfo entityTypeInfo[ENTITY_TYPE_COUNT] = { - (EntityTypeInfo){initAntifaShip, closeAntifaShip, updateAntifaShip, drawAntifaShip} + (EntityTypeInfo){initAntifaShip, closeAntifaShip, updateAntifaShip, drawAntifaShip}, + (EntityTypeInfo){initSoldato, closeSoldato, updateSoldato, drawSoldato} }; EntityVelocity entityVelocityIdentity() { @@ -32,7 +34,7 @@ Vector3 accelerateVector3(Vector3 value, Vector3 lastValue, Vector3 up, Vector3 }; } -Entity createEntity(EntityType type) { +Entity createEntity(EntityType type, Game * game) { EntityTypeInfo info = entityTypeInfo[type]; // Set defaults. @@ -49,7 +51,7 @@ Entity createEntity(EntityType type) { }; // Init. - info.initCb(&entity); + info.initCb(&entity, game); return entity; } @@ -60,10 +62,10 @@ void closeEntity(Entity * entity) { // Basic wireframe drawing. void entityDraw(Entity * entity) { - entity->model.transform = QuaternionToMatrix(entity->rotation); + entity->model->transform = QuaternionToMatrix(entity->rotation); DrawModelWires( - entity->model, + *entity->model, entity->position, 1, GREEN @@ -110,8 +112,8 @@ void entityJoystickControl(Entity * entity, Vector3 stick, float speed) { st = accelerateVector3( stick, entity->lastVelocity.stick, - Vector3Scale(entity->acceleration.rotationUp, t), - Vector3Scale(entity->acceleration.rotationDown, t) + Vector3Scale(entity->acceleration.rotation, t), + Vector3Scale(entity->acceleration.rotation, t) ); } diff --git a/src/entity.h b/src/entity.h index 7d27258..128365f 100644 --- a/src/entity.h +++ b/src/entity.h @@ -19,6 +19,7 @@ enum { typedef int8_t EntityType; typedef int16_t EntityId; // Id in world. +typedef uint32_t EntityFingerprint; // Callbacks. typedef void (*EntityUpdateCb)(Game * game, Entity * entity, EntityId id); @@ -26,8 +27,7 @@ typedef void (*EntityDrawCb)(Game * game, Entity * entity, EntityId id); // Acceleration indeed hehehe. typedef struct EntityAcceleration { - Vector3 rotationUp; - Vector3 rotationDown; + Vector3 rotation; float speedUp; float speedDown; } EntityAcceleration; @@ -46,8 +46,10 @@ EntityVelocity entityVelocityIdentity(); // This fucker is a entity. typedef struct Entity { + EntityId id; + EntityFingerprint fingerprint; EntityType type; - Model model; + Model * model; Vector3 position; Quaternion rotation; @@ -65,7 +67,7 @@ typedef struct Entity { void * data; } Entity; -typedef void (*EntityInitCb)(Entity * entity); +typedef void (*EntityInitCb)(Entity * entity, Game * game); typedef void (*EntityCloseCb)(Entity * entity); // Info for each entity type. @@ -79,7 +81,7 @@ typedef struct EntityTypeInfo { const extern EntityTypeInfo entityTypeInfo[ENTITY_TYPE_COUNT]; // Do I need a fucking comment? -Entity createEntity(EntityType type); +Entity createEntity(EntityType type, Game * game); void closeEntity(Entity * entity); // Helper functions for updating and drawing. @@ -4,23 +4,81 @@ void initGame(Game * game) { // Window. InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Killa Facsista"); + // Assets. + LoadAssets(&game->assets); + // Screen id. game->screenId = SCREEN_GAME; + // Main menu. + initMainMenu(game); + // Camera. initPlayerCamera(&game->playerCamera); - // Ship test. - game->ship = createEntity(ENTITY_ANTIFA); - SetTargetFPS(60); //DisableCursor(); + + // World. + initWorld(&game->world); + + // Debug. + // Add player. + addEntityToWorld( + &game->world, + createEntity(ENTITY_ANTIFA, game) + ); + + // Test entity. + Entity soldato = createEntity(ENTITY_SOLDATO, game); + soldato.position = (Vector3){10.0, 10.0, 10.0}; + addEntityToWorld(&game->world, soldato); + + soldato = createEntity(ENTITY_SOLDATO, game); + soldato.position = (Vector3){20.0, 20.0, 20.0}; + addEntityToWorld(&game->world, soldato); + + soldato = createEntity(ENTITY_SOLDATO, game); + soldato.position = (Vector3){30.0, 30.0, 30.0}; + addEntityToWorld(&game->world, soldato); + + printf("%d\n", removeEntityFromWorld(&game->world, 2)); + printf("%d\n", removeEntityFromWorld(&game->world, 3)); + + soldato = createEntity(ENTITY_SOLDATO, game); + soldato.position = (Vector3){-30.0, -30.0, -30.0}; + addEntityToWorld(&game->world, soldato); + + + puts("v"); + + for (int i = 0; i < game->world.vacantIdsCount; ++i) + printf("%d\n", game->world.vacantIds[i]); + + puts("l"); + + for (int i = 0; i < game->world.lookUpSize; ++i) { + printf("%d\n", game->world.lookUp[i]); + + Entity * e = getEntityFromWorld(game->world, i); + + if (e == NULL) { + puts("null"); + continue; + } + + if (e->id == i) + printf("good %x\n", e->fingerprint); + else + printf("bad %d\n", e->id); + } } void closeGame(Game * game) { - // Close ship test. - closeEntity(&game->ship); + unloadAssets(&game->assets); + freeWorld(&game->world); + // Close window last. CloseWindow(); } @@ -3,6 +3,8 @@ #include "gameScreen.h" #include "playerCamera.h" #include "entity.h" +#include "assets.h" +#include "world.h" #ifndef GAME_H #define GAME_H @@ -17,8 +19,8 @@ typedef struct Game { MainMenu mainMenu; GameScreen gameScreen; Camera3D playerCamera; - - Entity ship; + Assets assets; + World world; } Game; void initGame(Game * game); diff --git a/src/gameCommon.h b/src/gameCommon.h index 0d18d32..08ce5fe 100644 --- a/src/gameCommon.h +++ b/src/gameCommon.h @@ -22,13 +22,6 @@ typedef struct Entity Entity; #define WINDOW_WIDTH 960 #define WINDOW_HEIGHT 540 -// Bit shit. -#define SET_BIT(b, n) (b | (0x1 << n)) -#define CLEAR_BIT(b, n) (b & ~(0x1 << n)) -#define IS_BIT_SET(b, n) ((b >> n) & 0x1) -#define TOGGLE_BIT(b, n) (b ^ (0x1 << n)) -#define HAS_FLAG(v, f) ((v & f) == f) - // Memory management. #define KF_MALLOC(size) malloc(size) #define KF_CALLOC(nmemb, size) calloc(nmemb, size) diff --git a/src/gameScreen.c b/src/gameScreen.c index 893da0c..1eb6b55 100644 --- a/src/gameScreen.c +++ b/src/gameScreen.c @@ -1,7 +1,12 @@ #include "gameScreen.h" #include "game.h" +#include "world.h" void updateGameScreen(Game * game) { + + // Update world. + updateWorld(&game->world, game); + ClearBackground(BLACK); // Camera. @@ -11,7 +16,8 @@ void updateGameScreen(Game * game) { DrawGrid(500, 25.0); - game->ship.drawCb(game, &game->ship, 0); + // Draw world. + drawWorld(&game->world, game); EndMode3D(); } diff --git a/src/mainMenu.c b/src/mainMenu.c index 10f293a..fc67972 100644 --- a/src/mainMenu.c +++ b/src/mainMenu.c @@ -1,14 +1,46 @@ #include "mainMenu.h" #include "game.h" +void initMainMenu(Game * game) { + game->mainMenu = (MainMenu){ + .startButton = (Rectangle){0, 0, 100, 50}, + .logoTexture = &game->assets.textures[ICON128_ASSET] + }; + + resizeMainMenu(game); +} + void updateMainMenu(Game * game) { + MainMenu * mainMenu = &game->mainMenu; ClearBackground(RAYWHITE); - bool start = GuiButton( - (Rectangle){10, 10, 100, 50}, - "Start" + // Logo. + DrawTextureV( + *mainMenu->logoTexture, + mainMenu->logoPosition, + WHITE ); + // Start button. + bool start = GuiButton(mainMenu->startButton, "Start"); + if (start) game->screenId = SCREEN_GAME; + + if (IsWindowResized()) + resizeMainMenu(game); +} + +void resizeMainMenu(Game * game) { + MainMenu * mainMenu = &game->mainMenu; + + // Logo. + mainMenu->logoPosition = (Vector2){ + (GetScreenWidth() / 2.0) - (mainMenu->logoTexture->width / 2.0), + (GetScreenHeight() / 2.0) - (mainMenu->logoTexture->height * 1.50) + }; + + // Start button. + mainMenu->startButton.x = (GetScreenWidth() / 2.0) - (mainMenu->startButton.width / 2.0); + mainMenu->startButton.y = (GetScreenHeight() / 2.0) - (mainMenu->startButton.height / 2.0); } diff --git a/src/mainMenu.h b/src/mainMenu.h index 7dd5036..10ce855 100644 --- a/src/mainMenu.h +++ b/src/mainMenu.h @@ -4,8 +4,14 @@ #define MAIN_MENU_H typedef struct MainMenu { + Vector2 logoPosition; + Texture2D * logoTexture; + + Rectangle startButton; } MainMenu; +void initMainMenu(Game * game); void updateMainMenu(Game * game); +void resizeMainMenu(Game * game); #endif diff --git a/src/playerCamera.c b/src/playerCamera.c index d84d6d3..df2cce4 100644 --- a/src/playerCamera.c +++ b/src/playerCamera.c @@ -13,10 +13,12 @@ void initPlayerCamera(Camera3D * camera) { } void updatePlayerCamera(Camera3D * camera, Game * game) { + Entity * player = &game->world.entities[0]; + //UpdateCamera(camera, CAMERA_FIRST_PERSON); - camera->target = game->ship.position; + camera->target = player->position; - Matrix m = QuaternionToMatrix(QuaternionInvert(game->ship.rotation)); + Matrix m = QuaternionToMatrix(QuaternionInvert(player->rotation)); Vector3 pos = (Vector3){0.0, CAMERA_DIS/2, -CAMERA_DIS}; camera->position = (Vector3){ @@ -25,7 +27,7 @@ void updatePlayerCamera(Camera3D * camera, Game * game) { m.m8 * pos.x + m.m9 * pos.y + m.m10 * pos.z }; - camera->position = Vector3Add(camera->position, game->ship.position); + camera->position = Vector3Add(camera->position, player->position); camera->up = (Vector3){ m.m1 + m.m2, m.m5 + m.m6, @@ -3,6 +3,13 @@ #ifndef UTIL_H #define UTIL_H +// Bit shit. +#define SET_BIT(b, n) (b | (0x1 << n)) +#define CLEAR_BIT(b, n) (b & ~(0x1 << n)) +#define IS_BIT_SET(b, n) ((b >> n) & 0x1) +#define TOGGLE_BIT(b, n) (b ^ (0x1 << n)) +#define HAS_FLAG(v, f) ((v & f) == f) + typedef struct AxisAngle { Vector3 axis; float angle; diff --git a/src/world.c b/src/world.c index ea50eca..d76a2d3 100644 --- a/src/world.c +++ b/src/world.c @@ -1 +1,251 @@ #include "world.h" +#include "game.h" + +void initWorld(World * world) { + world->entities = NULL; + world->entitiesCount = 0; + + world->lookUp = NULL; + world->lookUpSize = 0; + + world->vacantIds = NULL; + world->vacantIdsCount = 0; + + // Set current fingerprint. + SetRandomSeed(time(NULL)); + + world->currentFingerprint = GetRandomValue( + FINGERPRINT_START_RANGE_MIN, + FINGERPRINT_START_RANGE_MAX + ); +} + +void freeWorld(World * world) { + int i; + + if (world->entities == NULL) + return; + + // Close entities. + for (i = 0; i < world->entitiesCount; ++i) + closeEntity(&world->entities[i]); + + KF_FREE(world->entities); + KF_FREE(world->lookUp); + + if (world->vacantIds != NULL) + KF_FREE(world->vacantIds); +} + +// Not for direct use. +KfError pushVacantId(World * world, EntityId id) { + ++world->vacantIdsCount; + + // Allocate. + if (world->vacantIds == NULL) + world->vacantIds = (EntityId*)KF_CALLOC(1, sizeof(EntityId)); + else + world->vacantIds = (EntityId*)KF_REALLOCARRAY( + world->vacantIds, + world->vacantIdsCount, + sizeof(EntityId) + ); + + if (world->vacantIds == NULL) { + ALLOCATION_ERROR; + return KFERROR; + } + + world->vacantIds[world->vacantIdsCount - 1] = id; + return KFSUCCESS; +} + +// Not for direct use. +EntityId popVacantId(World * world) { + EntityId id; + + // Already empty. + if (world->vacantIds == NULL) + return ENTITY_ID_NONE; + + id = world->vacantIds[world->vacantIdsCount - 1]; + + // Decrease count. + --world->vacantIdsCount; + + // Free or recallocate. + if (world->vacantIdsCount == 0) { + KF_FREE(world->vacantIds); + world->vacantIds = NULL; + } else { + world->vacantIds = (EntityId*)KF_REALLOCARRAY( + world->vacantIds, + world->vacantIdsCount, + sizeof(EntityId) + ); + } + + return id; +} + +Entity * getEntityFromWorld(World world, EntityId id) { + if (world.entities == NULL || id < 0 || id >= world.lookUpSize) + return NULL; + + int pos = world.lookUp[id]; + + if (pos == ENTITY_ID_NONE) + return NULL; + + return &world.entities[pos]; +} + +EntityId addEntityToWorld(World * world, Entity entity) { + EntityId id; + EntityId poppedId; + + Entity entityCopy = entity; + + // Set fingerprint. + entityCopy.fingerprint = world->currentFingerprint; + ++world->currentFingerprint; + + // Not allocated. + if (world->entities == NULL) { + // Allocate. + world->entities = (Entity*)KF_CALLOC(1, sizeof(Entity)); + world->lookUp = (EntityId*)KF_CALLOC(1, sizeof(EntityId)); + world->entitiesCount = 1; + world->lookUpSize = 1; + + if (world->entities == NULL || world->lookUp == NULL) { + ALLOCATION_ERROR; + return ENTITY_ID_NONE; + } + + // Set entity and id. + world->entities[0] = entityCopy; + world->entities[0].id = 0; + world->lookUp[0] = 0; + return 0; + } + + ++world->entitiesCount; + + // Resize. + world->entities = (Entity*)KF_REALLOCARRAY( + world->entities, + world->entitiesCount, + sizeof(Entity) + ); + + if (world->entities == NULL) { + ALLOCATION_ERROR; + return ENTITY_ID_NONE; + } + + // Set entity. + world->entities[world->entitiesCount - 1] = entityCopy; + + // Set look up. + poppedId = popVacantId(world); + + // Got popped id. + if (poppedId != ENTITY_ID_NONE) { + world->lookUp[poppedId] = world->entitiesCount - 1; + world->entities[world->entitiesCount - 1].id = poppedId; + return poppedId; + } + + ++world->lookUpSize; + + world->lookUp = (EntityId*)KF_REALLOCARRAY( + world->lookUp, + world->lookUpSize, + sizeof(EntityId) + ); + + if (world->lookUp == NULL) { + ALLOCATION_ERROR; + return ENTITY_ID_NONE; + } + + // Set id. + id = world->lookUpSize - 1; + world->entities[world->entitiesCount - 1].id = id; + world->lookUp[id] = world->entitiesCount - 1; + return id; +} + +KfError removeEntityFromWorld(World * world, EntityId id) { + int i; + int pos; + + if (world->entitiesCount == 1) + return KFERROR; + + // Get position in list. + pos = world->lookUp[id]; + + if (pos == ENTITY_ID_NONE) + return KFSUCCESS; + + // Close entity. + closeEntity(&world->entities[pos]); + + // Push id. + if (pushVacantId(world, id) != KFSUCCESS) + return KFERROR; + + // Move back entities. + for (i = pos; i < world->entitiesCount - 1; ++i) + world->entities[i] = world->entities[i + 1]; + + // Update lookup. + for (i = id + 1; i < world->lookUpSize; ++i) + --world->lookUp[i]; + + world->lookUp[id] = ENTITY_ID_NONE; + + // Resize entities. + --world->entitiesCount; + + world->entities = (Entity*)KF_REALLOCARRAY( + world->entities, + world->entitiesCount, + sizeof(Entity) + ); + + if (world->entities == NULL) { + ALLOCATION_ERROR; + return KFERROR; + } + + return KFSUCCESS; +} + +void updateWorld(World * world, Game * game) { + int i; + Entity * entity; + + for (i = 0; i < world->entitiesCount; ++i) { + entity = &world->entities[i]; + + // Call update callback. + if (entity->updateCb != NULL) + entity->updateCb(game, entity, i); + } +} + +void drawWorld(World * world, Game * game) { + int i; + Entity * entity; + + for (i = 0; i < world->entitiesCount; ++i) { + entity = &world->entities[i]; + + // Call draw callback. + if (entity->drawCb != NULL) + entity->drawCb(game, entity, i); + } +} diff --git a/src/world.h b/src/world.h index 379b920..b075301 100644 --- a/src/world.h +++ b/src/world.h @@ -4,4 +4,35 @@ #ifndef WORLD_H #define WORLD_H +#define FINGERPRINT_START_RANGE_MIN 0xf +#define FINGERPRINT_START_RANGE_MAX 0xff + +typedef struct World { + Entity * entities; + size_t entitiesCount; + + // For getting entity id; + EntityId * lookUp; + size_t lookUpSize; + + EntityId * vacantIds; + size_t vacantIdsCount; + + // Used for making fingerprints for entities. + EntityFingerprint currentFingerprint; +} World; + +void initWorld(World * world); +void freeWorld(World * world); + +#define ENTITY_ID_NONE -1 + +// ENTITY_ID_NONE on error. +Entity * getEntityFromWorld(World world, EntityId id); +EntityId addEntityToWorld(World * world, Entity entity); +KfError removeEntityFromWorld(World * world, EntityId id); + +void updateWorld(World * world, Game * game); +void drawWorld(World * world, Game * game); + #endif |