Browse Source

Implement geometry methods

Add geometry methods for point, vector, and rectangle.
master
TheoryOfNekomata 1 year ago
parent
commit
b8f5131fb9
17 changed files with 443 additions and 13 deletions
  1. +27
    -11
      CMakeLists.txt
  2. +7
    -2
      src/packages/game/IZ_app.h
  3. +1
    -0
      src/packages/game/core/IZ_creature.c
  4. +12
    -0
      src/packages/game/core/IZ_creature.h
  5. +1
    -0
      src/packages/game/core/IZ_entity.c
  6. +11
    -0
      src/packages/game/core/IZ_entity.h
  7. +1
    -0
      src/packages/game/core/IZ_object.c
  8. +15
    -0
      src/packages/game/core/IZ_object.h
  9. +8
    -0
      src/packages/game/geometry/IZ_point2d.c
  10. +13
    -0
      src/packages/game/geometry/IZ_point2d.h
  11. +26
    -0
      src/packages/game/geometry/IZ_rect.c
  12. +27
    -0
      src/packages/game/geometry/IZ_rect.h
  13. +22
    -0
      src/packages/game/geometry/IZ_vector2d.c
  14. +17
    -0
      src/packages/game/geometry/IZ_vector2d.h
  15. +244
    -0
      src/packages/game/geometry/geometry.test.c
  16. +1
    -0
      src/packages/game/memory/IZ_pool.c
  17. +10
    -0
      src/packages/game/memory/IZ_pool.h

+ 27
- 11
CMakeLists.txt View File

@@ -42,7 +42,8 @@ add_executable(
src/packages/game/input/IZ_keyboard.h
src/packages/game/IZ_config.c
src/packages/game/IZ_config.h
)
src/packages/game/geometry/IZ_point2d.c src/packages/game/geometry/IZ_point2d.h src/packages/game/geometry/IZ_vector2d.c src/packages/game/geometry/IZ_vector2d.h src/packages/game/geometry/IZ_rect.c src/packages/game/geometry/IZ_rect.h src/packages/game/core/IZ_object.c src/packages/game/core/IZ_object.h src/packages/game/core/IZ_creature.c src/packages/game/core/IZ_creature.h src/packages/game/core/IZ_entity.c src/packages/game/core/IZ_entity.h src/packages/game/memory/IZ_pool.c src/packages/game/memory/IZ_pool.h)

target_link_libraries(
game
SDL2main
@@ -50,20 +51,18 @@ target_link_libraries(
)

add_executable(
game-test-output
game-test-geometry
dependencies/bdd-for-c/bdd-for-c.h
src/packages/test/IZ_mock.h
src/packages/test/IZ_test.h

__mocks__/minIni.mock.h

src/packages/game/IZ_config.h
src/packages/game/__mocks__/IZ_config.mock.h

src/packages/game/output/IZ_video.h
src/packages/game/output/IZ_video.c
src/packages/game/output/output.test.c
)
src/packages/game/geometry/IZ_point2d.h
src/packages/game/geometry/IZ_point2d.c
src/packages/game/geometry/IZ_rect.h
src/packages/game/geometry/IZ_rect.c
src/packages/game/geometry/IZ_vector2d.h
src/packages/game/geometry/IZ_vector2d.c
src/packages/game/geometry/geometry.test.c)

add_executable(
game-test-input
@@ -88,6 +87,23 @@ add_executable(
src/packages/game/input/input.test.c
)


add_executable(
game-test-output
dependencies/bdd-for-c/bdd-for-c.h
src/packages/test/IZ_mock.h
src/packages/test/IZ_test.h

__mocks__/minIni.mock.h

src/packages/game/IZ_config.h
src/packages/game/__mocks__/IZ_config.mock.h

src/packages/game/output/IZ_video.h
src/packages/game/output/IZ_video.c
src/packages/game/output/output.test.c
)

if (WIN32)
add_custom_command(TARGET game POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake - E copy_if_different..."


+ 7
- 2
src/packages/game/IZ_app.h View File

@@ -4,16 +4,21 @@
#include "input/IZ_keyboard.h"
#include "input/IZ_joystick.h"
#include "output/IZ_video.h"
#include "memory/IZ_pool.h"
#include "IZ_action.h"

typedef struct {
IZ_VideoConfig video_config;

IZ_Action actions[PLAYERS];

// input
IZ_KeyboardState keyboard_state[PLAYERS];
IZ_JoystickState joystick_state[PLAYERS];

// output, video state
IZ_VideoConfig video_config;
uint64_t video_update_at;

IZ_Pool memory_pool;
} IZ_App;

int IZ_InitializeApp(IZ_App*);


+ 1
- 0
src/packages/game/core/IZ_creature.c View File

@@ -0,0 +1 @@
#include "IZ_creature.h"

+ 12
- 0
src/packages/game/core/IZ_creature.h View File

@@ -0,0 +1,12 @@
#ifndef IZ_CREATURE_H
#define IZ_CREATURE_H

#include "IZ_object.h"

typedef struct {
IZ_Object as_object;

float hp;
} IZ_Creature;

#endif

+ 1
- 0
src/packages/game/core/IZ_entity.c View File

@@ -0,0 +1 @@
#include "IZ_entity.h"

+ 11
- 0
src/packages/game/core/IZ_entity.h View File

@@ -0,0 +1,11 @@
#ifndef IZ_ENTITY_H
#define IZ_ENTITY_H

#include "../geometry/IZ_point2d.h"

typedef struct {
IZ_Point2D pos;
// TODO object appearance (sprite, sprites contain bounding boxes, collisions contain bounding boxes)
} IZ_Entity;

#endif

+ 1
- 0
src/packages/game/core/IZ_object.c View File

@@ -0,0 +1 @@
#include "IZ_object.h"

+ 15
- 0
src/packages/game/core/IZ_object.h View File

@@ -0,0 +1,15 @@
#ifndef IZ_OBJECT_H
#define IZ_OBJECT_H

#include "../geometry/IZ_vector2d.h"
#include "../geometry/IZ_rect.h"
#include "IZ_entity.h"

typedef struct {
IZ_Entity as_entity;

IZ_Rect collision_rect;
IZ_Vector2D speed;
} IZ_Object;

#endif

+ 8
- 0
src/packages/game/geometry/IZ_point2d.c View File

@@ -0,0 +1,8 @@
#include "IZ_point2d.h"

IZ_Point2D IZ_PointTranslate(IZ_Point2D point, IZ_Coordinate translate_x, IZ_Coordinate translate_y) {
return (IZ_Point2D) {
.x = point.x + translate_x,
.y = point.y + translate_y,
};
}

+ 13
- 0
src/packages/game/geometry/IZ_point2d.h View File

@@ -0,0 +1,13 @@
#ifndef IZ_POINT2D_H
#define IZ_POINT2D_H

typedef float IZ_Coordinate;

typedef struct {
IZ_Coordinate x;
IZ_Coordinate y;
} IZ_Point2D;

IZ_Point2D IZ_PointTranslate(IZ_Point2D, IZ_Coordinate, IZ_Coordinate);

#endif

+ 26
- 0
src/packages/game/geometry/IZ_rect.c View File

@@ -0,0 +1,26 @@
#include "IZ_rect.h"

IZ_Bounds IZ_RectGetBounds(IZ_Rect rect) {
return (IZ_Bounds) {
.left = rect.pos.x,
.top = rect.pos.y,
.right = rect.pos.x + rect.width,
.bottom = rect.pos.y + rect.height,
};
}

bool IZ_BoundsContainPoint(IZ_Bounds bounds, IZ_Point2D point) {
return (
bounds.left <= point.x
&& bounds.top <= point.y
&& point.x <= bounds.right
&& point.y <= bounds.bottom
);
}

bool IZ_BoundsCollide(IZ_Bounds a, IZ_Bounds b) {
return (
b.left < a.right
&& b.top < a.bottom
);
}

+ 27
- 0
src/packages/game/geometry/IZ_rect.h View File

@@ -0,0 +1,27 @@
#ifndef IZ_RECT_H
#define IZ_RECT_H

#include <stdbool.h>
#include "IZ_point2d.h"

typedef struct {
IZ_Coordinate left;
IZ_Coordinate top;
IZ_Coordinate right;
IZ_Coordinate bottom;
} IZ_Bounds;

typedef struct {
// top left
IZ_Point2D pos;
IZ_Coordinate width;
IZ_Coordinate height;
} IZ_Rect;

IZ_Bounds IZ_RectGetBounds(IZ_Rect);

bool IZ_BoundsContainPoint(IZ_Bounds, IZ_Point2D);

bool IZ_BoundsCollide(IZ_Bounds, IZ_Bounds);

#endif

+ 22
- 0
src/packages/game/geometry/IZ_vector2d.c View File

@@ -0,0 +1,22 @@
#include "IZ_vector2d.h"

IZ_Vector2D IZ_VectorAdd(IZ_Vector2D addend, IZ_Vector2D augend) {
return (IZ_Vector2D) {
.right = addend.right + augend.right,
.up = addend.up + augend.up,
};
}

IZ_Vector2D IZ_VectorMultiply(IZ_Vector2D multiplicand, IZ_Vector2D multiplier) {
return (IZ_Vector2D) {
.right = multiplicand.right * multiplier.right,
.up = multiplicand.up * multiplier.up,
};
}

IZ_Vector2D IZ_VectorScale(IZ_Vector2D vector, IZ_VectorMagnitude scalar) {
return (IZ_Vector2D) {
.right = vector.right * scalar,
.up = vector.up * scalar,
};
}

+ 17
- 0
src/packages/game/geometry/IZ_vector2d.h View File

@@ -0,0 +1,17 @@
#ifndef IZ_VECTOR2D_H
#define IZ_VECTOR2D_H

typedef float IZ_VectorMagnitude;

typedef struct {
IZ_VectorMagnitude right;
IZ_VectorMagnitude up;
} IZ_Vector2D;

IZ_Vector2D IZ_VectorAdd(IZ_Vector2D, IZ_Vector2D);

IZ_Vector2D IZ_VectorMultiply(IZ_Vector2D, IZ_Vector2D);

IZ_Vector2D IZ_VectorScale(IZ_Vector2D, IZ_VectorMagnitude);

#endif

+ 244
- 0
src/packages/game/geometry/geometry.test.c View File

@@ -0,0 +1,244 @@
#include "../../test/IZ_test.h"
#include "IZ_point2d.h"
#include "IZ_vector2d.h"
#include "IZ_rect.h"

spec("geometry") {
describe("point2d") {
describe("PointTranslate") {
it("translates coordinates of a point") {
static IZ_Point2D input = {
.x = 420.f,
.y = 1337.f,
};

static IZ_Point2D expected = {
.x = 426.f,
.y = 1346.f,
};

static IZ_Point2D actual;
actual = IZ_PointTranslate(input, 6.f, 9.f);

check(expected.x == actual.x, "X values do not match.");
check(expected.y == actual.y, "Y values do not match.");
}
}
}

describe("vector2d") {
describe("VectorAdd") {
it("adds two vectors") {
static IZ_Vector2D addend = {
.right = 420.f,
.up = 1337.f,
};

static IZ_Vector2D augend = {
.right = 6.f,
.up = 9.f,
};

static IZ_Vector2D expected_sum = {
.right = 426.f,
.up = 1346.f,
};

static IZ_Vector2D actual_sum;
actual_sum = IZ_VectorAdd(addend, augend);

check(expected_sum.right == actual_sum.right, "Right values do not match.");
check(expected_sum.up == actual_sum.up, "Up values do not match.");
}
}

describe("VectorMultiply") {
it("multiplies two vectors") {
static IZ_Vector2D multiplicand = {
.right = 6.f,
.up = 9.f,
};

static IZ_Vector2D multiplier = {
.right = 3.f,
.up = 2.f,
};

static IZ_Vector2D expected_product = {
.right = 18.f,
.up = 18.f,
};

static IZ_Vector2D actual_product;
actual_product = IZ_VectorMultiply(multiplicand, multiplier);

check(expected_product.right == actual_product.right, "Right values do not match.");
check(expected_product.up == actual_product.up, "Up values do not match.");
}
}
describe("VectorScale") {
it("scales a vector") {
static IZ_Vector2D v = {
.right = 420.f,
.up = 69.f,
};

static IZ_VectorMagnitude s = 2.f;

static IZ_Vector2D expected = {
.right = 840.f,
.up = 138.f,
};

static IZ_Vector2D actual;
actual = IZ_VectorScale(v, s);

check(expected.right == actual.right, "Right values do not match.");
check(expected.up == actual.up, "Up values do not match.");
}
}
}

describe("rect") {
describe("RectGetBounds") {
it("returns the bounds of a rectangle") {
static IZ_Rect r = {
.pos = {
.x = 50,
.y = 100,
},
.width = 150,
.height = 200,
};

static IZ_Bounds expected = {
.left = 50,
.top = 100,
.right = 200,
.bottom = 300,
};

static IZ_Bounds actual;
actual = IZ_RectGetBounds(r);

check(expected.left == actual.left, "Left values do not match.");
check(expected.top == actual.top, "Top values do not match.");
check(expected.right == actual.right, "Right values do not match.");
check(expected.bottom == actual.bottom, "Bottom values do not match.");
}
}

describe("BoundsContainPoint") {
it("returns true for points inside bounds") {
static IZ_Bounds b = {
.left = 50,
.top = 100,
.right = 200,
.bottom = 300,
};

static IZ_Point2D p = {
.x = 75,
.y = 150,
};

check(IZ_BoundsContainPoint(b, p), "Point not found inside bounds.");
}

it("returns true for points along bounds edge") {
static IZ_Bounds b = {
.left = 50,
.top = 100,
.right = 200,
.bottom = 300,
};

static IZ_Point2D p1 = {
.x = 50,
.y = 100,
};

static IZ_Point2D p2 = {
.x = 200,
.y = 300,
};

check(IZ_BoundsContainPoint(b, p1), "Point p1 not found inside bounds.");
check(IZ_BoundsContainPoint(b, p2), "Point p2 not found inside bounds.");
}

it("returns false for points outside bounds") {
static IZ_Bounds b = {
.left = 50,
.top = 100,
.right = 200,
.bottom = 300,
};

static IZ_Point2D p = {
.x = 0,
.y = 0,
};

check(!IZ_BoundsContainPoint(b, p), "Point found inside bounds.");
}
}

describe("BoundsCollide") {
it("returns true for bounds A inside bounds B") {
static IZ_Bounds a = {
.left = 100,
.top = 125,
.right = 150,
.bottom = 200,
};

static IZ_Bounds b = {
.left = 50,
.top = 75,
.right = 200,
.bottom = 250,
};

check(IZ_BoundsCollide(a, b), "Bounds not colliding.");
}

it("returns true for bounds A intersecting bounds B") {
static IZ_Bounds a = {
.left = 0,
.top = 0,
.right = 150,
.bottom = 200,
};

static IZ_Bounds b = {
.left = 50,
.top = 75,
.right = 200,
.bottom = 250,
};

check(IZ_BoundsCollide(a, b), "Bounds not colliding.");
}

it("returns true for bounds A outside bounds B") {
static IZ_Bounds a = {
.left = 50,
.top = 75,
.right = 200,
.bottom = 250,
};

static IZ_Bounds b = {
.left = 550,
.top = 575,
.right = 800,
.bottom = 850,
};

check(!IZ_BoundsCollide(a, b), "Bounds colliding.");
}
}
}
}

+ 1
- 0
src/packages/game/memory/IZ_pool.c View File

@@ -0,0 +1 @@
#include "IZ_pool.h"

+ 10
- 0
src/packages/game/memory/IZ_pool.h View File

@@ -0,0 +1,10 @@
#ifndef IZ_POOL_H
#define IZ_POOL_H

#define POOL_MAX_SIZE 256

typedef struct {
// TODO allocate and implement pool memory management!
} IZ_Pool;

#endif

Loading…
Cancel
Save