Nimbin2git.christianimmanuel.de / Games / Entropie / object.c

Entropie git · main

git clone https://git.christianimmanuel.de/games/Entropie.gitwget https://git.christianimmanuel.de/games/Entropie/archive/Entropie.tar.gz
object.c 3.8 KB · 126 lines raw
#include "object.h"
#include "camera.h"

#include <stdlib.h>
#include <stdio.h>


void object_log(const Object* obj) {
    if (!obj) {
        printf("Object: NULL\n");
        return;
    }

    printf("Object Debug Info:\n");
    printf("  Type: %d\n", obj->parent_type);
    printf("  Position: (%.2f, %.2f)\n", obj->x, obj->y);
    printf("  Size: %.2fx%.2f\n", obj->w, obj->h);
    printf("  Parent Pointer: %p\n", obj->parent);
    printf("  Prev: %p | Next: %p\n", (void*)obj->prev, (void*)obj->next);
}

Object* Object_create() {
    Object* obj = (Object*)malloc(sizeof(Object));
    if (!obj) fprintf(stderr, "Failed allocate Object_create()");
    obj->prev = NULL;
    obj->next = NULL;
    return obj;
}
Object* Object_create_pos(float x, float y, float w, float h) {
    Object* o = Object_create();
    o->x = x;
    o->y = y;
    o->w = w;
    o->h = h;
    o->prev = NULL;
    o->next = NULL;
    return o;
}

char Object_is_visible(Object* obj, Camera* camera) {
    if (!obj || !camera) return 0;

    float obj_left   = obj->x;
    float obj_right  = obj->x + obj->w;
    float obj_top    = obj->y;
    float obj_bottom = obj->y + obj->h;

    float cam_left   = camera->offset_x;
    float cam_right  = camera->offset_x + camera->view_w;
    float cam_top    = camera->offset_y;
    float cam_bottom = camera->offset_y + camera->view_h;

    return !(obj_right < cam_left ||  // Object is left of the view
             obj_left > cam_right ||  // Object is right of the view
             obj_bottom < cam_top ||  // Object is above the view
             obj_top > cam_bottom);   // Object is below the view
}


// Helper function: compute the z-index of an object (e.g., bottom edge)
static inline float get_z_index(const Object *obj) {
    return obj->y + (obj->parent_type == Object_Tile ? 0 : obj->h );
}

// Insertion function: insert obj_new into the doubly linked list starting at reference.
// This function will traverse backward or forward from the reference to find the proper spot.
// After insertion, obj_new is correctly linked into the list.
Object* Object_add(Object *reference, Object *obj_new) {
    if (!obj_new) {
        fprintf(stderr, "NULL passed in Object_add()\n");
        return NULL;
    }

    // Unlink from doubly linked list
    if (obj_new->prev) {
        obj_new->prev->next = obj_new->next;
    }
    if (obj_new->next) {
        obj_new->next->prev = obj_new->prev;
    }
    // Initialize the new object's pointers
    obj_new->prev = NULL;
    obj_new->next = NULL;

    // Calculate the new object's z-index
    float new_z = get_z_index(obj_new);

    // Start from the reference node
    Object *current = reference;
    float current_z = get_z_index(current);

    if (new_z < current_z) {
        // We need to move backwards: find the first node whose z-index is less than or equal to new_z
        while (current->prev != NULL && get_z_index(current->prev) > new_z) {
            current = current->prev;
        }
        // Insert obj_new before current
        obj_new->next = current;
        obj_new->prev = current->prev;
        if (current->prev != NULL) {
            current->prev->next = obj_new;
        }
        current->prev = obj_new;
    } else {
        // new_z is greater than or equal to current_z; move forward until we find a node with a greater z-index
        while (current->next != NULL && get_z_index(current->next) <= new_z) {
            current = current->next;
        }
        // Insert obj_new after current
        obj_new->prev = current;
        obj_new->next = current->next;
        if (current->next != NULL) {
            current->next->prev = obj_new;
        }
        current->next = obj_new;
    }
    return obj_new;
}

void Objects_free(Object* first) {
    while (first) {
        Object* next = first->next;
        free(first);
        first = next;
    }
}