diff --git a/archive/rpg/CMakeLists.txt b/archive/rpg/CMakeLists.txt deleted file mode 100644 index 4178186..0000000 --- a/archive/rpg/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2025 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -# Sources -target_sources(${DUSK_TARGET_NAME} - PRIVATE - rpg.c -) - -# Subdirs -add_subdirectory(entity) -add_subdirectory(world) \ No newline at end of file diff --git a/archive/rpg/entity/CMakeLists.txt b/archive/rpg/entity/CMakeLists.txt deleted file mode 100644 index f1edcfd..0000000 --- a/archive/rpg/entity/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2025 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -# Sources -target_sources(${DUSK_TARGET_NAME} - PRIVATE - entity.c - npc.c - player.c - direction.c -) \ No newline at end of file diff --git a/archive/rpg/entity/direction.c b/archive/rpg/entity/direction.c deleted file mode 100644 index aa04586..0000000 --- a/archive/rpg/entity/direction.c +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "direction.h" -#include "assert/assert.h" - -float_t directionToAngle(const direction_t dir) { - switch(dir) { - case DIRECTION_NORTH: return (M_PI_2); - case DIRECTION_SOUTH: return -(M_PI_2); - case DIRECTION_EAST: return 0; - case DIRECTION_WEST: return (M_PI); - default: return 0; // Should never happen - } -} - -void directionGetVec2(const direction_t dir, vec2 out) { - assertNotNull(out, "Output vector cannot be NULL"); - - switch(dir) { - case DIRECTION_NORTH: - out[0] = 0.0f; - out[1] = 1.0f; - break; - - case DIRECTION_SOUTH: - out[0] = 0.0f; - out[1] = -1.0f; - break; - - case DIRECTION_EAST: - out[0] = 1.0f; - out[1] = 0.0f; - break; - - case DIRECTION_WEST: - out[0] = -1.0f; - out[1] = 0.0f; - break; - - default: - assertUnreachable("Invalid direction"); - } -} \ No newline at end of file diff --git a/archive/rpg/entity/direction.h b/archive/rpg/entity/direction.h deleted file mode 100644 index 54b9c11..0000000 --- a/archive/rpg/entity/direction.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -typedef enum { - DIRECTION_SOUTH = 0, - DIRECTION_EAST = 1, - DIRECTION_WEST = 2, - DIRECTION_NORTH = 3, - - DIRECTION_UP = DIRECTION_NORTH, - DIRECTION_DOWN = DIRECTION_SOUTH, - DIRECTION_LEFT = DIRECTION_WEST, - DIRECTION_RIGHT = DIRECTION_EAST, -} direction_t; - -/** - * Converts a direction to an angle in float_t format. - * - * @param dir The direction to convert. - * @return The angle corresponding to the direction. - */ -float_t directionToAngle(const direction_t dir); - -/** - * Converts a direction to a vec2 unit vector. - * - * @param dir The direction to convert. - * @param out Pointer to the vec2 array to populate. - */ -void directionGetVec2(const direction_t dir, vec2 out); \ No newline at end of file diff --git a/archive/rpg/entity/entity.c b/archive/rpg/entity/entity.c deleted file mode 100644 index c9ab810..0000000 --- a/archive/rpg/entity/entity.c +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "entity.h" -#include "rpg/world/map.h" -#include "assert/assert.h" -#include "util/memory.h" -#include "display/tileset/tileset_entities.h" -#include "time/time.h" -#include "util/math.h" - -void entityInit(entity_t *entity, const entitytype_t type, map_t *map) { - assertNotNull(entity, "Entity pointer cannot be NULL"); - assertNotNull(map, "Map pointer cannot be NULL"); - assertTrue(type < ENTITY_TYPE_COUNT, "Invalid entity type"); - assertTrue(type != ENTITY_TYPE_NULL, "Cannot have NULL entity type"); - - memoryZero(entity, sizeof(entity_t)); - entity->type = type; - entity->map = map; - - // Init. I did use a callback struct but it was not flexible enough. - switch(type) { - case ENTITY_TYPE_PLAYER: - playerInit(entity); - break; - - case ENTITY_TYPE_NPC: - npcInit(entity); - break; - - default: - break; - } -} - -void entityUpdate(entity_t *entity) { - assertNotNull(entity, "Entity pointer cannot be NULL"); - assertTrue(entity->type < ENTITY_TYPE_COUNT, "Invalid entity type"); - assertTrue(entity->type != ENTITY_TYPE_NULL, "Cannot have NULL entity type"); - - // Handle movement logic - switch(entity->type) { - case ENTITY_TYPE_PLAYER: - playerMovement(entity); - break; - - case ENTITY_TYPE_NPC: - npcUpdate(entity); - break; - - default: - break; - } - - // Apply velocity - if(entity->velocity[0] != 0.0f || entity->velocity[1] != 0.0f) { - entity->position[0] += entity->velocity[0] * TIME.delta; - entity->position[1] += entity->velocity[1] * TIME.delta; - - // Hit test on other entities. - entity_t *start = entity->map->entities; - entity_t *end = &entity->map->entities[entity->map->entityCount]; - - // Our hitbox - physicscircle_t self; - glm_vec2_copy(entity->position, self.position); - self.radius = TILESET_ENTITIES.tileWidth / 2.0f; - - physicscircle_t other; - other.radius = self.radius; - - // TODO: what if multiple collisions? - do { - if(start == entity) continue; - if(start->type == ENTITY_TYPE_NULL) continue; - glm_vec2_copy(start->position, other.position); - - physicscirclecircleresult_t result; - physicsCircleCheckCircle(self, other, &result); - - if(result.hit) { - entity->position[0] -= result.normal[0] * result.depth; - entity->position[1] -= result.normal[1] * result.depth; - break; - } - } while((start++) != end); - - // Friction (and dampening) - entity->velocity[0] *= ENTITY_FRICTION * TIME.delta; - entity->velocity[1] *= ENTITY_FRICTION * TIME.delta; - if(mathAbs(entity->velocity[0]) < ENTITY_MIN_VELOCITY) { - entity->velocity[0] = 0.0f; - } - if(mathAbs(entity->velocity[1]) < ENTITY_MIN_VELOCITY) { - entity->velocity[1] = 0.0f; - } - } - - if(entity->type == ENTITY_TYPE_PLAYER) { - playerInteraction(entity); - } -} \ No newline at end of file diff --git a/archive/rpg/entity/entity.h b/archive/rpg/entity/entity.h deleted file mode 100644 index 0015c48..0000000 --- a/archive/rpg/entity/entity.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "direction.h" -#include "rpg/entity/player.h" -#include "npc.h" -#include "physics/physics.h" - -#define ENTITY_FRICTION 0.9f -#define ENTITY_MIN_VELOCITY 0.05f - -typedef struct map_s map_t; - -typedef enum { - ENTITY_TYPE_NULL, - ENTITY_TYPE_PLAYER, - ENTITY_TYPE_NPC, - - ENTITY_TYPE_COUNT -} entitytype_t; - -typedef struct entity_s { - map_t *map; - entitytype_t type; - direction_t direction; - - vec2 position; - vec2 velocity; - - union { - player_t player; - npc_t npc; - }; -} entity_t; - -/** - * Initializes an entity structure. - * - * @param entity Pointer to the entity structure to initialize. - * @param type The type of the entity. - * @param map Pointer to the map the entity belongs to. - */ -void entityInit(entity_t *entity, const entitytype_t type, map_t *map); - -/** - * Updates an entity. - * - * @param entity Pointer to the entity structure to update. - */ -void entityUpdate(entity_t *entity); \ No newline at end of file diff --git a/archive/rpg/entity/npc.c b/archive/rpg/entity/npc.c deleted file mode 100644 index 79d21d6..0000000 --- a/archive/rpg/entity/npc.c +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "entity.h" -#include "assert/assert.h" - -void npcInit(entity_t *entity) { - assertNotNull(entity, "Entity pointer cannot be NULL"); -} - -void npcUpdate(entity_t *entity) { - assertNotNull(entity, "Entity pointer cannot be NULL"); -} \ No newline at end of file diff --git a/archive/rpg/entity/npc.h b/archive/rpg/entity/npc.h deleted file mode 100644 index b22754f..0000000 --- a/archive/rpg/entity/npc.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -typedef struct entity_s entity_t; - -typedef struct { - void *nothing; -} npc_t; - -/** - * Initializes an NPC entity. - * - * @param entity Pointer to the entity structure to initialize. - */ -void npcInit(entity_t *entity); - -/** - * Updates an NPC entity. - * - * @param entity Pointer to the entity structure to update. - */ -void npcUpdate(entity_t *entity); \ No newline at end of file diff --git a/archive/rpg/entity/player.c b/archive/rpg/entity/player.c deleted file mode 100644 index 1246e35..0000000 --- a/archive/rpg/entity/player.c +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "entity.h" -#include "assert/assert.h" -#include "input/input.h" -#include "display/scene/overworld/sceneoverworld.h" -#include "display/tileset/tileset_entities.h" - -void playerInit(entity_t *entity) { - assertNotNull(entity, "Entity pointer cannot be NULL"); -} - -void playerMovement(entity_t *entity) { - assertNotNull(entity, "Entity pointer cannot be NULL"); - - // Update velocity. - vec2 dir = { - inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT), - inputAxis(INPUT_ACTION_DOWN, INPUT_ACTION_UP) - }; - if(dir[0] == 0 && dir[1] == 0) return; - - glm_vec2_normalize(dir); - entity->velocity[0] += PLAYER_SPEED * dir[0]; - entity->velocity[1] += PLAYER_SPEED * dir[1]; - - // Update direction. - if(dir[0] > 0) { - if(entity->direction == DIRECTION_RIGHT) { - entity->direction = DIRECTION_RIGHT; - } else { - if(dir[1] < 0) { - entity->direction = DIRECTION_UP; - } else if(dir[1] > 0) { - entity->direction = DIRECTION_DOWN; - } else { - entity->direction = DIRECTION_RIGHT; - } - } - } else if(dir[0] < 0) { - if(entity->direction == DIRECTION_LEFT) { - entity->direction = DIRECTION_LEFT; - } else { - if(dir[1] < 0) { - entity->direction = DIRECTION_UP; - } else if(dir[1] > 0) { - entity->direction = DIRECTION_DOWN; - } else { - entity->direction = DIRECTION_LEFT; - } - } - } else if(dir[1] < 0) { - entity->direction = DIRECTION_UP; - } else if(dir[1] > 0) { - entity->direction = DIRECTION_DOWN; - } -} - -void playerInteraction(entity_t *entity) { - assertNotNull(entity, "Entity pointer cannot be NULL"); - - if(!inputPressed(INPUT_ACTION_ACCEPT)) return; - - physicsbox_t interactBox; - - // Get direction vector - directionGetVec2(entity->direction, interactBox.min); - - // Scale by interact range - glm_vec2_scale(interactBox.min, PLAYER_INTERACTION_RANGE, interactBox.min); - - // Add entity position, this makes the center of the box. - glm_vec2_add(interactBox.min, entity->position, interactBox.min); - - // Copy to max - glm_vec2_copy(interactBox.min, interactBox.max); - - // Size of the hitbox - vec2 halfSize = { - TILESET_ENTITIES.tileWidth * PLAYER_INTERACTION_SIZE * 0.5f, - TILESET_ENTITIES.tileHeight * PLAYER_INTERACTION_SIZE * 0.5f - }; - - // Subtract from min, add to max. - glm_vec2_sub(interactBox.min, halfSize, interactBox.min); - glm_vec2_add(interactBox.max, halfSize, interactBox.max); - - // For each entity - entity_t *start = entity->map->entities; - entity_t *end = &entity->map->entities[entity->map->entityCount]; - vec2 otherSize = { TILESET_ENTITIES.tileWidth, TILESET_ENTITIES.tileHeight }; - physicsbox_t otherBox; - physicsboxboxresult_t result; - - do { - if(start->type != ENTITY_TYPE_NPC) continue; - - // Setup other box. - glm_vec2_copy(start->position, otherBox.min); - glm_vec2_copy(start->position, otherBox.max); - glm_vec2_sub(otherBox.min, otherSize, otherBox.min); - glm_vec2_add(otherBox.min, otherSize, otherBox.max); - - physicsBoxCheckBox(interactBox, otherBox, &result); - if(!result.hit) continue; - - printf("Interacted with entity at (%.2f, %.2f)\n", start->position[0], start->position[1]); - break; - } while(++start != end); -} \ No newline at end of file diff --git a/archive/rpg/entity/player.h b/archive/rpg/entity/player.h deleted file mode 100644 index efb3326..0000000 --- a/archive/rpg/entity/player.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -#define PLAYER_SPEED 64.0f -#define PLAYER_INTERACTION_RANGE 1.0f -#define PLAYER_INTERACTION_SIZE 0.5f - -typedef struct entity_s entity_t; - -typedef struct { - void *nothing; -} player_t; - -/** - * Initializes a player entity. - * - * @param entity Pointer to the entity structure to initialize. - */ -void playerInit(entity_t *entity); - -/** - * Handles movement logic for the player entity. - * - * @param entity Pointer to the player entity structure. - */ -void playerMovement(entity_t *entity); - -/** - * Handles interaction logic for the player entity. - * - * @param entity Pointer to the player entity structure. - */ -void playerInteraction(entity_t *entity); \ No newline at end of file diff --git a/archive/rpg/game.c b/archive/rpg/game.c deleted file mode 100644 index 40298d0..0000000 --- a/archive/rpg/game.c +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "game/game.h" - -errorret_t gameInit(void) { - printf("Init RPG\n"); - errorOk(); -} - -void gameUpdate(void) { - -} - -void gameDispose(void) { - -} \ No newline at end of file diff --git a/archive/rpg/overworld/CMakeLists.txt b/archive/rpg/overworld/CMakeLists.txt deleted file mode 100644 index b5ce235..0000000 --- a/archive/rpg/overworld/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2025 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -# Sources -target_sources(${DUSK_TARGET_NAME} - PRIVATE - sceneoverworld.c -) \ No newline at end of file diff --git a/archive/rpg/overworld/sceneoverworld.c b/archive/rpg/overworld/sceneoverworld.c deleted file mode 100644 index 3c49511..0000000 --- a/archive/rpg/overworld/sceneoverworld.c +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "sceneoverworld.h" -#include "rpg/entity/entity.h" -#include "display/spritebatch.h" -#include "display/framebuffer.h" -#include "display/scene/scenemanager.h" -#include "display/mesh/quad.h" -#include "asset/assetmanager.h" -#include "assert/assert.h" - -#include "display/tileset/tileset_entities.h" - -sceneoverworld_t SCENE_OVERWORLD; -asset_t *testAsset; -ref_t testAssetRef; - -errorret_t sceneOverworldInit(void) { - cameraInit(&SCENE_OVERWORLD.camera); - glm_vec3_copy((vec3){ 0.0f, 1.0f, 0.0f }, SCENE_OVERWORLD.camera.lookat.up); - SCENE_OVERWORLD.camera.perspective.fov = 45; - SCENE_OVERWORLD.camera.farClip = 10000.0f; - - scene_t *scene = &SCENE_MANAGER_SCENES[SCENE_TYPE_OVERWORLD]; - scene->flags |= SCENE_FLAG_ACTIVE | SCENE_FLAG_VISIBLE; - - errorChain(assetManagerLoadAsset( - TILESET_ENTITIES.image, &testAsset, &testAssetRef - )); - - errorOk(); -} - -void sceneOverworldUpdate(void) { - if(RPG.map == NULL) return; - - // Move camera to player. - const entity_t *start = &RPG.map->entities[0]; - const entity_t *end = &RPG.map->entities[RPG.map->entityCount]; - while(start < end) { - if(start->type == ENTITY_TYPE_PLAYER) { - SCENE_OVERWORLD.camera.lookat.target[0] = start->position[0]; - SCENE_OVERWORLD.camera.lookat.target[1] = start->position[1]; - break; - } - start++; - } -} - -void sceneOverworldRender(void) { - const float_t camOffset = 12.0f; - const float_t fbWidth = frameBufferGetWidth(FRAMEBUFFER_BOUND); - const float_t fbHeight = frameBufferGetHeight(FRAMEBUFFER_BOUND); - const float_t aspect = fbWidth / fbHeight; - const float_t pixelPerfectOffset = tanf( - (glm_rad(180) - SCENE_OVERWORLD.camera.perspective.fov) / 2.0f - ) * (fbHeight/ 2.0f); - - // glm_vec3_copy((vec3){ - // -100.0f, -100.0f, 0.0f - // }, SCENE_OVERWORLD.camera.lookat.target); - glm_vec3_copy((vec3){ - SCENE_OVERWORLD.camera.lookat.target[0], - SCENE_OVERWORLD.camera.lookat.target[1] + camOffset, - SCENE_OVERWORLD.camera.lookat.target[2] + pixelPerfectOffset - }, SCENE_OVERWORLD.camera.lookat.position); - - cameraPushMatrix(&SCENE_OVERWORLD.camera); - - if(RPG.map != NULL) sceneOverworldRenderMap(RPG.map); - - spriteBatchFlush(); - cameraPopMatrix(); -} - -void sceneOverworldRenderMap(const map_t *map) { - assertNotNull(map, "Map pointer cannot be NULL"); - - // Draw base layer - sceneOverworldRenderMapLayer(map, &map->base); - - // Draw entities - const entity_t *start = &map->entities[0]; - const entity_t *end = &map->entities[map->entityCount]; - while(start < end) { - // Render entity here. - sceneOverworldRenderEntity(start); - start++; - } - spriteBatchFlush(); - - // Draw overlay layer. - sceneOverworldRenderMapLayer(map, &map->overlay); -} - -void sceneOverworldRenderEntity(const entity_t *entity) { - assertNotNull(entity, "Entity pointer cannot be NULL"); - assertTrue(entity->type < ENTITY_TYPE_COUNT, "Invalid entity type"); - assertTrue(entity->type != ENTITY_TYPE_NULL, "Cannot have NULL entity type"); - - vec4 uv; - tilesetPositionGetUV(&TILESET_ENTITIES, entity->direction, 0, uv); - - // For now, just draw a placeholder quad. - spriteBatchPush( - &testAsset->paletteImage.texture, - entity->position[0], entity->position[1], - entity->position[0] + TILESET_ENTITIES.tileWidth, - entity->position[1] + TILESET_ENTITIES.tileHeight, - COLOR_WHITE, - uv[0], uv[1], uv[2], uv[3] - ); -} - -void sceneOverworldRenderMapLayer(const map_t *map, const maplayer_t *layer) { - assertNotNull(layer, "Map layer pointer cannot be NULL"); - - for(uint32_t y = 0; y < map->height; y++) { - for(uint32_t x = 0; x < map->width; x++) { - const tile_t *tile = &layer->tiles[y * map->width + x]; - if(tile->id == 0) continue; - - spriteBatchPush( - NULL, - x * TILESET_ENTITIES.tileWidth, - y * TILESET_ENTITIES.tileHeight, - (x + 1) * TILESET_ENTITIES.tileWidth, - (y + 1) * TILESET_ENTITIES.tileHeight, - COLOR_RED, - 0, 0, 1, 1 - ); - } - } - - spriteBatchFlush(); -} - -void sceneOverworldDispose(void) { - // Dispose of the overworld scene. - if(testAsset) assetUnlock(testAsset, testAssetRef); -} \ No newline at end of file diff --git a/archive/rpg/overworld/sceneoverworld.h b/archive/rpg/overworld/sceneoverworld.h deleted file mode 100644 index 7297125..0000000 --- a/archive/rpg/overworld/sceneoverworld.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "display/camera.h" -#include "rpg/rpg.h" -#include "error/error.h" - -typedef struct { - camera_t camera; -} sceneoverworld_t; - -extern sceneoverworld_t SCENE_OVERWORLD; - -/** - * Initialize the overworld scene. - */ -errorret_t sceneOverworldInit(void); - -/** - * Update the overworld scene. - */ -void sceneOverworldUpdate(void); - -/** - * Render the overworld scene. - */ -void sceneOverworldRender(void); - -/** - * Render a map in the overworld scene. - * - * @param map Pointer to the map to render. - */ -void sceneOverworldRenderMap(const map_t *map); - -/** - * Render an entity in the overworld scene. - * - * @param entity Pointer to the entity to render. - */ -void sceneOverworldRenderEntity(const entity_t *entity); - -/** - * Render a map layer in the overworld scene. - * - * @param map Pointer to the map the layer belongs to. - * @param layer Pointer to the map layer to render. - */ -void sceneOverworldRenderMapLayer(const map_t *map, const maplayer_t *layer); - -/** - * Dispose of the overworld scene. - */ -void sceneOverworldDispose(void); \ No newline at end of file diff --git a/archive/rpg/rpg.c b/archive/rpg/rpg.c deleted file mode 100644 index 0be87fb..0000000 --- a/archive/rpg/rpg.c +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "rpg.h" -#include "rpg/world/map.h" -#include "util/memory.h" -#include "asset/assetmanager.h" - -rpg_t RPG; - -asset_t *asset; -ref_t assetRef; - -void rpgInit() { - memoryZero(&RPG, sizeof(RPG)); - - errorret_t ret = assetManagerLoadAsset("map/untitled.drm", &asset, &assetRef); - if(ret.code != ERROR_OK) { - errorPrint(ret); - errorCatch(ret); - return; - } - RPG.map = &asset->rpgMap.map; - - // mapInit(&testMap); - // testMap.width = 2; - // testMap.height = 2; - // for(uint32_t i = 0; i < testMap.width * testMap.height; i++) { - // testMap.base.tiles[i].id = 1; - // } - - // entity_t *ent = mapEntityAdd(&testMap); - // entityInit(ent, ENTITY_TYPE_PLAYER, &testMap); - - // entity_t *npc = mapEntityAdd(&testMap); - // entityInit(npc, ENTITY_TYPE_NPC, &testMap); - // npc->position[0] = 32.0f; - // npc->position[1] = 32.0f; -} - -void rpgUpdate() { - if(RPG.map != NULL) { - mapUpdate(RPG.map); - } -} \ No newline at end of file diff --git a/archive/rpg/rpg.h b/archive/rpg/rpg.h deleted file mode 100644 index e7b1b3c..0000000 --- a/archive/rpg/rpg.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "rpg/world/map.h" - -typedef struct { - map_t *map; -} rpg_t; - -extern rpg_t RPG; - -/** - * Initializes the RPG subsystem. - */ -void rpgInit(); - -/** - * Updates the RPG subsystem. - */ -void rpgUpdate(); \ No newline at end of file diff --git a/archive/rpg/screen.c b/archive/rpg/screen.c deleted file mode 100644 index a570a01..0000000 --- a/archive/rpg/screen.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "screen.h" -#include "assert/assert.h" -#include "display/spritebatch.h" - -screen_t SCREEN; - -void screenInit(void) { - // Virtual backbuffer for dynamic resolution scaling - #if DISPLAY_SIZE_DYNAMIC == 1 - frameBufferInit(&SCREEN.frameBuffer, DISPLAY_WIDTH, DISPLAY_HEIGHT); - cameraInit(&SCREEN.frameBufferCamera); - SCREEN.frameBufferCamera.projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC; - SCREEN.frameBufferCamera.viewType = CAMERA_VIEW_TYPE_MATRIX; - glm_lookat( - (vec3){0.0f, 0.0f, 1.0f}, - (vec3){0.0f, 0.0f, 0.0f}, - (vec3){0.0f, 1.0f, 0.0f}, - SCREEN.frameBufferCamera.view - ); - SCREEN.frameBufferCamera.nearClip = -1.0f; - SCREEN.frameBufferCamera.farClip = 1.0f; - #endif -} - -void screenBind(void) { - #if DISPLAY_SIZE_DYNAMIC == 1 - frameBufferBind(&SCREEN.frameBuffer); - #else - frameBufferBind(NULL); - #endif - - frameBufferClear( - FRAMEBUFFER_CLEAR_COLOR | FRAMEBUFFER_CLEAR_DEPTH, - COLOR_CORNFLOWER_BLUE - ); -} - -void screenUnbindAndRender(void) { - assertTrue(SPRITEBATCH.spriteCount == 0, "Sprite batch not flushed"); - - // Render to real backbuffer - #if DISPLAY_SIZE_DYNAMIC == 1 - frameBufferBind(NULL); - frameBufferClear( - FRAMEBUFFER_CLEAR_COLOR | FRAMEBUFFER_CLEAR_DEPTH, - COLOR_BLACK - ); - - - SCREEN.frameBufferCamera.orthographic.left = 0; - SCREEN.frameBufferCamera.orthographic.right = frameBufferGetWidth( - FRAMEBUFFER_BOUND - ); - SCREEN.frameBufferCamera.orthographic.bottom = frameBufferGetHeight( - FRAMEBUFFER_BOUND - ); - SCREEN.frameBufferCamera.orthographic.top = 0; - cameraPushMatrix(&SCREEN.frameBufferCamera); - - vec2 backbuffer = { - (float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND), - (float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND) - }; - vec2 virtual = { - (float_t)frameBufferGetWidth(&SCREEN.frameBuffer), - (float_t)frameBufferGetHeight(&SCREEN.frameBuffer) - }; - - // Compare aspect ratios. - vec4 viewport; - float_t backbufferAspect = backbuffer[0] / backbuffer[1]; - float_t virtualAspect = virtual[0] / virtual[1]; - if (backbufferAspect > virtualAspect) { - // Backbuffer is wider: pillarbox - float_t scale = backbuffer[1] / virtual[1]; - float_t width = virtual[0] * scale; - viewport[0] = (backbuffer[0] - width) * 0.5f; - viewport[1] = 0; - viewport[2] = width; - viewport[3] = backbuffer[1]; - } else { - // Backbuffer is taller: letterbox - float_t scale = backbuffer[0] / virtual[0]; - float_t height = virtual[1] * scale; - viewport[0] = 0; - viewport[1] = (backbuffer[1] - height) * 0.5f; - viewport[2] = backbuffer[0]; - viewport[3] = height; - } - - spriteBatchPush( - &SCREEN.frameBuffer.texture, - viewport[0], viewport[1], - viewport[0] + viewport[2], viewport[1] + viewport[3], - COLOR_WHITE, - 0.0f, 1.0f, 1.0f, 0.0f - ); - spriteBatchFlush(); - cameraPopMatrix(); - #endif -} - -void screenDispose(void) { - frameBufferDispose(&SCREEN.frameBuffer); -} \ No newline at end of file diff --git a/archive/rpg/screen.h b/archive/rpg/screen.h deleted file mode 100644 index 41b58a5..0000000 --- a/archive/rpg/screen.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "display/camera.h" -#include "display/framebuffer.h" - -typedef struct { - #if DISPLAY_SIZE_DYNAMIC == 1 - framebuffer_t frameBuffer; - camera_t frameBufferCamera; - #else - void *empty; - #endif -} screen_t; - -extern screen_t SCREEN; - -/** - * Initializes the screen. - */ -void screenInit(void); - -/** - * Binds the screen for rendering. - */ -void screenBind(void); - -/** - * Unbinds the screen and renders it. - */ -void screenUnbindAndRender(void); - -/** - * Disposes of the screen. - */ -void screenDispose(void); \ No newline at end of file diff --git a/archive/rpg/test/CMakeLists.txt b/archive/rpg/test/CMakeLists.txt deleted file mode 100644 index 02f9e89..0000000 --- a/archive/rpg/test/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2025 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -# Sources -target_sources(${DUSK_TARGET_NAME} - PRIVATE - scenetest.c -) \ No newline at end of file diff --git a/archive/rpg/test/scenetest.c b/archive/rpg/test/scenetest.c deleted file mode 100644 index 8ccc3c2..0000000 --- a/archive/rpg/test/scenetest.c +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "scenetest.h" -#include "display/scene/scenemanager.h" -#include "display/spritebatch.h" - -scenetest_t SCENE_TEST; - -errorret_t sceneTestInit(void) { - cameraInit(&SCENE_TEST.camera); - SCENE_TEST.camera.projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC; - SCENE_TEST.camera.nearClip = -1.0f; - SCENE_TEST.camera.farClip = 2.0f; - - SCENE_TEST.camera.viewType = CAMERA_VIEW_TYPE_2D; - SCENE_TEST.camera._2d.zoom = 2.0f; - SCENE_TEST.camera._2d.position[0] = -150.0f; - SCENE_TEST.camera._2d.position[1] = -50.0f; - - scene_t *scene = &SCENE_MANAGER_SCENES[SCENE_TYPE_TEST]; - scene->flags |= SCENE_FLAG_ACTIVE | SCENE_FLAG_VISIBLE; - - errorOk(); -} - -void sceneTestUpdate(void) { -} - -void sceneTestRender(void) { - SCENE_TEST.camera.orthographic.left = 0.0f; - SCENE_TEST.camera.orthographic.right = frameBufferGetWidth(FRAMEBUFFER_BOUND); - SCENE_TEST.camera.orthographic.top = frameBufferGetHeight(FRAMEBUFFER_BOUND); - SCENE_TEST.camera.orthographic.bottom = 0.0f; - - cameraPushMatrix(&SCENE_TEST.camera); - spriteBatchClear(); - - spriteBatchFlush(); - cameraPopMatrix(); -} - -void sceneTestDispose(void) { -} diff --git a/archive/rpg/test/scenetest.h b/archive/rpg/test/scenetest.h deleted file mode 100644 index 69de23d..0000000 --- a/archive/rpg/test/scenetest.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "display/camera.h" -#include "error/error.h" - -typedef struct { - camera_t camera; -} scenetest_t; - -extern scenetest_t SCENE_TEST; - -/** - * Initialize the test scene. - */ -errorret_t sceneTestInit(void); - -/** - * Update the test scene. - */ -void sceneTestUpdate(void); - -/** - * Render the test scene. - */ -void sceneTestRender(void); - -/** - * Dispose of the test scene. - */ -void sceneTestDispose(void); \ No newline at end of file diff --git a/archive/rpg/world/CMakeLists.txt b/archive/rpg/world/CMakeLists.txt deleted file mode 100644 index ea50569..0000000 --- a/archive/rpg/world/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2025 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -# Sources -target_sources(${DUSK_TARGET_NAME} - PRIVATE - map.c -) \ No newline at end of file diff --git a/archive/rpg/world/map.c b/archive/rpg/world/map.c deleted file mode 100644 index 3c4182e..0000000 --- a/archive/rpg/world/map.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "map.h" -#include "util/memory.h" -#include "assert/assert.h" - -void mapInit(map_t *map) { - assertNotNull(map, "Map cannot be NULL"); - memoryZero(map, sizeof(map_t)); -} - -void mapUpdate(map_t *map) { - assertNotNull(map, "Map cannot be NULL"); - - entity_t *start = &map->entities[0]; - entity_t *end = &map->entities[map->entityCount]; - while(start < end) { - entityUpdate(start++); - } -} - -entity_t * mapEntityAdd(map_t *map) { - assertNotNull(map, "Map cannot be NULL"); - assertTrue(map->entityCount < MAP_ENTITY_COUNT_MAX, "Map entities full"); - - entity_t *entity = &map->entities[map->entityCount++]; - return entity; -} \ No newline at end of file diff --git a/archive/rpg/world/map.h b/archive/rpg/world/map.h deleted file mode 100644 index 2c9834b..0000000 --- a/archive/rpg/world/map.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2025 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "rpg/entity/entity.h" - -#define MAP_ENTITY_COUNT_MAX 32 - -#define MAP_WIDTH_MAX 64 -#define MAP_HEIGHT_MAX 64 -#define MAP_TILE_COUNT_MAX (MAP_WIDTH_MAX * MAP_HEIGHT_MAX) -#define MAP_LAYER_COUNT_MAX 2 - -typedef struct { - uint8_t id; -} tile_t; - -typedef struct { - tile_t tiles[MAP_TILE_COUNT_MAX]; -} maplayer_t; - -typedef struct map_s { - entity_t entities[MAP_ENTITY_COUNT_MAX]; - uint8_t entityCount; - - uint8_t width, height; - maplayer_t base; - maplayer_t overlay; -} map_t; - -extern map_t testMap; - -/** - * Initializes a map structure. - * - * @param map Pointer to the map structure to initialize. - */ -void mapInit(map_t *map); - -/** - * Updates the map and its entities. - * - * @param map Pointer to the map structure to update. - */ -void mapUpdate(map_t *map); - -/** - * Adds (but does not initialize) an entity on the map. - * - * @param map Pointer to the map structure. - * @return Pointer to the added entity. - */ -entity_t * mapEntityAdd(map_t *map); \ No newline at end of file diff --git a/src/main.c b/src/main.c index ccbe4b6..6104a12 100644 --- a/src/main.c +++ b/src/main.c @@ -8,8 +8,6 @@ #include "engine/engine.h" #include "console/console.h" - - int main(int argc, char **argv) { errorret_t ret; ret = engineInit(); diff --git a/src/rpg/rpg.c b/src/rpg/rpg.c index 91a5971..df88092 100644 --- a/src/rpg/rpg.c +++ b/src/rpg/rpg.c @@ -7,6 +7,7 @@ #include "rpg.h" #include "entity/entity.h" +#include "rpg/world/world.h" #include "time/time.h" #include "rpgcamera.h" #include "util/memory.h" @@ -14,8 +15,13 @@ errorret_t rpgInit(void) { memoryZero(ENTITIES, sizeof(ENTITIES)); + // Init the world. + worldInit(); + + // Initialize the camera rpgCameraInit(); + // TEST: Create some entities. entity_t *ent; ent = &ENTITIES[0]; entityInit(ent, ENTITY_TYPE_PLAYER); @@ -27,18 +33,26 @@ errorret_t rpgInit(void) { entityInit(ent, ENTITY_TYPE_NPC); ent->position[0] = 6, ent->position[1] = 6; + // All Good! errorOk(); } void rpgUpdate(void) { if(!TIME.fixedUpdate) return; + // TODO: Do not update if the scene is not the map scene? + + // Update the world. + worldUpdate(); + + // Update overworld ents. entity_t *ent = &ENTITIES[0]; do { if(ent->type == ENTITY_TYPE_NULL) continue; entityUpdate(ent); } while(++ent < &ENTITIES[ENTITY_COUNT]); + // Update the camera. rpgCameraUpdate(); } diff --git a/src/rpg/world/CMakeLists.txt b/src/rpg/world/CMakeLists.txt index 15c3bec..08b0b7c 100644 --- a/src/rpg/world/CMakeLists.txt +++ b/src/rpg/world/CMakeLists.txt @@ -6,4 +6,5 @@ # Sources target_sources(${DUSK_TARGET_NAME} PRIVATE + world.c ) \ No newline at end of file diff --git a/src/rpg/world/chunk.h b/src/rpg/world/chunk.h new file mode 100644 index 0000000..0bf00b5 --- /dev/null +++ b/src/rpg/world/chunk.h @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "rpg/world/tile.h" + +#define CHUNK_WIDTH 16 +#define CHUNK_HEIGHT 16 +#define CHUNK_DEPTH 16 +#define CHUNK_TILE_COUNT (CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH) + +typedef struct chunk_s { + int16_t x, y, z; + tile_t tiles[CHUNK_TILE_COUNT]; +} chunk_t; \ No newline at end of file diff --git a/archive/rpg/world/tile.h b/src/rpg/world/region.h similarity index 69% rename from archive/rpg/world/tile.h rename to src/rpg/world/region.h index 566fb2d..0b72c09 100644 --- a/archive/rpg/world/tile.h +++ b/src/rpg/world/region.h @@ -6,11 +6,9 @@ */ #pragma once - -typedef enum { - TILE_TYPE_NULL, -} tiletype_t; +#include "dusk.h" typedef struct { - tiletype_t type; -} tile_t; \ No newline at end of file + vec2 min; + vec2 max; +} region_t; \ No newline at end of file diff --git a/src/rpg/world/tile.h b/src/rpg/world/tile.h new file mode 100644 index 0000000..c4bee1f --- /dev/null +++ b/src/rpg/world/tile.h @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "dusk.h" + +#pragma pack(push, 1) +typedef struct tile_s { + uint8_t id; +} tile_t; +#pragma pack(pop) \ No newline at end of file diff --git a/src/rpg/world/world.c b/src/rpg/world/world.c new file mode 100644 index 0000000..c0f6a8c --- /dev/null +++ b/src/rpg/world/world.c @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "world.h" +#include "util/memory.h" + +world_t WORLD; + +void worldInit() { + memoryZero(&WORLD, sizeof(world_t)); + + for(uint32_t i = 0; i < WORLD_CHUNK_COUNT; i++) { + WORLD.chunkOrder[i] = &WORLD.chunks[i]; + } +} + +void worldUpdate() { + +} \ No newline at end of file diff --git a/src/rpg/world/world.h b/src/rpg/world/world.h new file mode 100644 index 0000000..68090cc --- /dev/null +++ b/src/rpg/world/world.h @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "rpg/world/chunk.h" + +#define WORLD_WIDTH 4 +#define WORLD_HEIGHT 4 +#define WORLD_DEPTH 4 +#define WORLD_CHUNK_COUNT (WORLD_WIDTH * WORLD_HEIGHT * WORLD_DEPTH) + +typedef struct world_s { + chunk_t chunks[WORLD_CHUNK_COUNT]; + chunk_t *chunkOrder[WORLD_CHUNK_COUNT]; + int16_t x, y, z; +} world_t; + +extern world_t WORLD; + +/** + * Initializes the world. + */ +void worldInit(); + +/** + * Updates the world. + */ +void worldUpdate(); \ No newline at end of file diff --git a/src/scene/scene/scenemap.c b/src/scene/scene/scenemap.c index 55b6dde..8c1a259 100644 --- a/src/scene/scene/scenemap.c +++ b/src/scene/scene/scenemap.c @@ -17,6 +17,7 @@ #define TILE_SIZE 16 errorret_t sceneMapInit(scenedata_t *data) { + // Init the camera. cameraInitPerspective(&data->sceneMap.camera); data->sceneMap.camera.projType = CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED; data->sceneMap.camera.viewType = CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT; @@ -36,6 +37,7 @@ errorret_t sceneMapInit(scenedata_t *data) { } void sceneMapUpdate(scenedata_t *data) { + } void sceneMapRender(scenedata_t *data) { diff --git a/src/scene/scene/scenemap.h b/src/scene/scene/scenemap.h index 83db5f9..54a7b7f 100644 --- a/src/scene/scene/scenemap.h +++ b/src/scene/scene/scenemap.h @@ -8,11 +8,12 @@ #pragma once #include "scene/scene.h" #include "rpg/entity/entity.h" +#include "rpg/world/world.h" #include "display/camera.h" typedef struct { - int32_t nothing; camera_t camera; + world_t world; } scenemap_t; errorret_t sceneMapInit(scenedata_t *data);