diff --git a/assets/config/init.dcf b/assets/config/init.dcf index 69fac34..1b80542 100644 --- a/assets/config/init.dcf +++ b/assets/config/init.dcf @@ -1,6 +1,5 @@ exec "config/init-base"; -screen height 270; screen height 270; bind ` toggleconsole; diff --git a/src/display/camera.c b/src/display/camera.c index 064dc07..680cd32 100644 --- a/src/display/camera.c +++ b/src/display/camera.c @@ -98,6 +98,34 @@ void cameraPushMatrix(camera_t *camera) { ); break; + case CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT: + assertTrue( + camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE || + camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED, + "Pixel perfect camera view requires perspective projection" + ); + + const float_t viewportHeight = ( + (float_t)frameBufferGetHeight(FRAMEBUFFER_BOUND) + ); + const float_t z = (viewportHeight / 2.0f) / ( + camera->lookatPixelPerfect.pixelsPerUnit * + tanf(camera->perspective.fov / 2.0f) + ); + + vec3 position; + glm_vec3_copy(camera->lookatPixelPerfect.target, position); + glm_vec3_add(position, camera->lookatPixelPerfect.offset, position); + position[2] += z; + + glm_lookat( + position, + camera->lookatPixelPerfect.target, + camera->lookatPixelPerfect.up, + view + ); + break; + case CAMERA_VIEW_TYPE_2D: glm_mat4_identity(view); glm_translate(view, (vec3){ diff --git a/src/display/camera.h b/src/display/camera.h index 08dde36..6a7ae88 100644 --- a/src/display/camera.h +++ b/src/display/camera.h @@ -20,7 +20,8 @@ typedef enum { typedef enum { CAMERA_VIEW_TYPE_MATRIX, CAMERA_VIEW_TYPE_LOOKAT, - CAMERA_VIEW_TYPE_2D + CAMERA_VIEW_TYPE_2D, + CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT } cameraviewtype_t; typedef struct { @@ -36,6 +37,13 @@ typedef struct { float_t up[3]; } lookat; + struct { + float_t offset[3]; + float_t target[3]; + float_t up[3]; + float_t pixelsPerUnit; + } lookatPixelPerfect; + struct { float_t position[2]; float_t zoom; diff --git a/src/rpg/entity/player.c b/src/rpg/entity/player.c index 121513c..6386175 100644 --- a/src/rpg/entity/player.c +++ b/src/rpg/entity/player.c @@ -81,36 +81,36 @@ void playerInteraction(entity_t *entity) { // 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 - }; + // // Size of the hitbox + // vec2 halfSize = { + // 1 * PLAYER_INTERACTION_SIZE * 0.5f, + // 1 * 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); + // // 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 = ENTITIES; - entity_t *end = &ENTITIES[ENTITY_COUNT]; - vec2 otherSize = { TILESET_ENTITIES.tileWidth, TILESET_ENTITIES.tileHeight }; - physicsbox_t otherBox; - physicsboxboxresult_t result; + // // For each entity + // entity_t *start = ENTITIES; + // entity_t *end = &ENTITIES[ENTITY_COUNT]; + // vec2 otherSize = { 1, 1 }; + // physicsbox_t otherBox; + // physicsboxboxresult_t result; - do { - if(start->type != ENTITY_TYPE_NPC) continue; + // 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); + // // 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; + // 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); + // 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/src/scene/scene/scenemap.c b/src/scene/scene/scenemap.c index a59286f..55b6dde 100644 --- a/src/scene/scene/scenemap.c +++ b/src/scene/scene/scenemap.c @@ -14,11 +14,23 @@ #include "rpg/rpgcamera.h" #include "util/memory.h" -#define TILE_SIZE 1 +#define TILE_SIZE 16 errorret_t sceneMapInit(scenedata_t *data) { cameraInitPerspective(&data->sceneMap.camera); data->sceneMap.camera.projType = CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED; + data->sceneMap.camera.viewType = CAMERA_VIEW_TYPE_LOOKAT_PIXEL_PERFECT; + glm_vec3_zero(data->sceneMap.camera.lookatPixelPerfect.offset); + data->sceneMap.camera.lookatPixelPerfect.offset[2] = 32.0f; + glm_vec3_copy( + (vec3){ 0.0f, 0.0f, 0.0f }, + data->sceneMap.camera.lookatPixelPerfect.target + ); + glm_vec3_copy( + (vec3){ 0.0f, 1.0f, 0.0f }, + data->sceneMap.camera.lookatPixelPerfect.up + ); + data->sceneMap.camera.lookatPixelPerfect.pixelsPerUnit = 1.0f; errorOk(); } @@ -27,49 +39,20 @@ void sceneMapUpdate(scenedata_t *data) { } void sceneMapRender(scenedata_t *data) { - // Look at target. glm_vec3_scale( RPG_CAMERA.position, TILE_SIZE, - data->sceneMap.camera.lookat.target + data->sceneMap.camera.lookatPixelPerfect.target ); // Center within tile glm_vec3_add( - data->sceneMap.camera.lookat.target, + data->sceneMap.camera.lookatPixelPerfect.target, (vec3){TILE_SIZE / 2.0f, TILE_SIZE / 2.0f, TILE_SIZE / 2.0f }, - data->sceneMap.camera.lookat.target + data->sceneMap.camera.lookatPixelPerfect.target ); - // Apply pixel perfect offset and camera offset - const float_t camOffset = 0.01f; - const float_t pixelPerfectOffset = tanf( - data->sceneMap.camera.perspective.fov / 2.0f - ) * ((float_t)SCREEN.height / 2.0f); - - glm_vec3_copy((vec3){ - data->sceneMap.camera.lookat.target[0], - data->sceneMap.camera.lookat.target[1] + camOffset, - data->sceneMap.camera.lookat.target[2] + pixelPerfectOffset - }, data->sceneMap.camera.lookat.position); - - // TESTING ONLY - camera_t backup = data->sceneMap.camera; - cameraInitOrthographic(&data->sceneMap.camera); - data->sceneMap.camera.projType = CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC; - glm_vec3_copy((vec3){ - RPG_CAMERA.position[0] * TILE_SIZE, - RPG_CAMERA.position[1] * TILE_SIZE, - 10.0f - }, data->sceneMap.camera._2d.position); - data->sceneMap.camera.orthographic.left = 0.0f; - data->sceneMap.camera.orthographic.right = SCREEN.width; - data->sceneMap.camera.orthographic.top = 0.0f; - data->sceneMap.camera.orthographic.bottom = SCREEN.height; - data->sceneMap.camera.nearClip = -100.0f; - data->sceneMap.camera.farClip = 100.0f; - // Push camera cameraPushMatrix(&data->sceneMap.camera); @@ -82,9 +65,6 @@ void sceneMapRender(scenedata_t *data) { // Finished, pop back camera. cameraPopMatrix(); - - //END TESTING - data->sceneMap.camera = backup; } void sceneMapRenderEntity(entity_t *entity) { @@ -93,8 +73,7 @@ void sceneMapRenderEntity(entity_t *entity) { if(entity->type == ENTITY_TYPE_NULL) return; vec3 posMin, posMax; - // glm_vec3_scale(entity->position, TILE_SIZE, posMin); - posMin[0] = 1, posMin[1] = 1, posMin[2] = 0; + glm_vec3_scale(entity->position, TILE_SIZE, posMin); glm_vec3_add(posMin, (vec3){TILE_SIZE, TILE_SIZE, TILE_SIZE }, posMax); vec2 uv0 = { 0.0f, 0.0f }; diff --git a/tools/assetstool/processtileset.py b/tools/assetstool/processtileset.py index 15570c1..242471c 100644 --- a/tools/assetstool/processtileset.py +++ b/tools/assetstool/processtileset.py @@ -135,12 +135,14 @@ def processTileset(asset): data += f" .image = {json.dumps(tilesetData['image']['imagePath'])},\n" data += f"}};\n" + # Write Header outputFile = os.path.join(args.headers_dir, "display", "tileset", f"tileset_{tilesetName}.h") os.makedirs(os.path.dirname(outputFile), exist_ok=True) with open(outputFile, 'w') as f: f.write(data) + print(f"Write header for tileset: {outputFile}") tileset = { "files": [],