+2
include/keraforge.h
+2
include/keraforge.h
+3
include/keraforge/_header.h
+3
include/keraforge/_header.h
+28
-3
include/keraforge/actor.h
+28
-3
include/keraforge/actor.h
···
1
#ifndef __kf_actor__
2
#define __kf_actor__
3
4
#include <keraforge/_header.h>
5
#include <keraforge/math.h>
6
#include <keraforge/world.h>
···
8
#include <keraforge/sprites.h>
9
#include <raylib.h>
10
11
struct kf_actor
12
{
13
struct kf_spritesheet sprites;
14
-
struct kf_vec2(f32) pos, vel, size, sizeoffset;
15
-
f32 speed, speedmod, friction;
16
-
bool collide, controlled;
17
enum kf_direction pointing;
18
void (*tick)(struct kf_world *world, struct kf_actor *self);
19
void (*draw)(struct kf_world *world, struct kf_actor *self);
20
};
21
22
struct kf_actor *kf_actor_new(struct kf_spritesheet sprites, f32 width, f32 height, bool collides);
23
24
/* Load a spritesheet, filling in the details for loading character spritesheets. */
···
32
void kf_actor_move(struct kf_world *world, struct kf_actor *actor, f32 deltatime);
33
/* Draw the actor. */
34
void kf_actor_draw(struct kf_actor *actor);
35
36
#endif
···
1
#ifndef __kf_actor__
2
#define __kf_actor__
3
4
+
5
#include <keraforge/_header.h>
6
#include <keraforge/math.h>
7
#include <keraforge/world.h>
···
9
#include <keraforge/sprites.h>
10
#include <raylib.h>
11
12
+
13
+
/* Represents any kinematic body in the world (players, NPCs, etc). */
14
struct kf_actor
15
{
16
+
/* Spritesheet for the actor. */
17
struct kf_spritesheet sprites;
18
+
/* The actor's position. */
19
+
struct kf_vec2(f32) pos;
20
+
/* The actor's velocity. */
21
+
struct kf_vec2(f32) vel;
22
+
/* The actor's size. Default origin is 0,0. */
23
+
struct kf_vec2(f32) size;
24
+
/* An offset to apply to the actor's collision rect. */
25
+
struct kf_vec2(f32) sizeoffset;
26
+
/* Actor's speed. */
27
+
f32 speed;
28
+
/* Speed modifier for the actor. Gets multiplied by the actor's speed when moving. */
29
+
f32 speedmod;
30
+
/* Friction to apply to the actor while moving. */
31
+
f32 friction;
32
+
/* Indicates if collision processing should be applied to this actor. */
33
+
bool collide;
34
+
/* When true, the actor's `pointing` field is expected to be updated manually. */
35
+
bool controlled;
36
+
/* The direction that the actor is pointing. */
37
enum kf_direction pointing;
38
+
/* Called every frame to update the actor. Don't forget about deltatime (kf_dts, kf_dtms)! */
39
void (*tick)(struct kf_world *world, struct kf_actor *self);
40
+
/* Called every frame to render the actor. */
41
void (*draw)(struct kf_world *world, struct kf_actor *self);
42
};
43
44
+
45
+
/* Create a new actor. */
46
struct kf_actor *kf_actor_new(struct kf_spritesheet sprites, f32 width, f32 height, bool collides);
47
48
/* Load a spritesheet, filling in the details for loading character spritesheets. */
···
56
void kf_actor_move(struct kf_world *world, struct kf_actor *actor, f32 deltatime);
57
/* Draw the actor. */
58
void kf_actor_draw(struct kf_actor *actor);
59
+
60
61
#endif
+3
include/keraforge/fs.h
+3
include/keraforge/fs.h
···
1
#ifndef __kf_fs__
2
#define __kf_fs__
3
4
#include <keraforge/_header.h>
5
6
/* Check if a file exists. */
7
int kf_exists(char *filename);
···
10
u8 *kf_readbin(char *filename, size_t *plen);
11
/* Write binary file contents. */
12
int kf_writebin(char *filename, u8 *data, size_t len);
13
14
#endif
···
1
#ifndef __kf_fs__
2
#define __kf_fs__
3
4
+
5
#include <keraforge/_header.h>
6
+
7
8
/* Check if a file exists. */
9
int kf_exists(char *filename);
···
12
u8 *kf_readbin(char *filename, size_t *plen);
13
/* Write binary file contents. */
14
int kf_writebin(char *filename, u8 *data, size_t len);
15
+
16
17
#endif
+3
include/keraforge/graphics.h
+3
include/keraforge/graphics.h
+26
-2
include/keraforge/input.h
+26
-2
include/keraforge/input.h
···
1
#ifndef __kf_input__
2
#define __kf_input__
3
4
#include <keraforge/_header.h>
5
#include <raylib.h>
6
7
#define MOUSE_BUTTON_UNKNOWN ((MouseButton)-1)
8
#define GAMEPAD_AXIS_UNKNOWN ((GamepadAxis)-1)
···
11
typedef u8 kf_inputbind_t;
12
#define KF_INPUTBIND_NONE ((kf_inputbind_t)0)
13
14
struct _kf_inputbinds
15
{
16
kf_inputbind_t count; /* must start at 1. 0 is the `none` keybind. */
17
char *id[KF_INPUTBIND_MAX];
18
KeyboardKey key[KF_INPUTBIND_MAX];
19
MouseButton mouse[KF_INPUTBIND_MAX];
20
GamepadButton gamepad[KF_INPUTBIND_MAX];
21
GamepadAxis axis[KF_INPUTBIND_MAX];
22
};
23
24
/* Deadzone for gamepads. Default is 0.2f. */
25
extern f32 kf_deadzone;
26
-
27
extern struct _kf_inputbinds kf_inputbinds;
28
29
/* Add a new input binding. */
30
-
kf_inputbind_t kf_addinput(char *id, KeyboardKey key, MouseButton mouse, GamepadButton gamepad, GamepadAxis axis);
31
/* Get an input's index by it's translation key. */
32
kf_inputbind_t kf_getinput(char *id);
33
34
int kf_checkkeypress(kf_inputbind_t id);
35
int kf_checkkeyrelease(kf_inputbind_t id);
36
int kf_checkkeydown(kf_inputbind_t id);
37
int kf_checkkeyup(kf_inputbind_t id);
38
int kf_checkmousepress(kf_inputbind_t id);
39
int kf_checkmouserelease(kf_inputbind_t id);
40
int kf_checkmousedown(kf_inputbind_t id);
41
int kf_checkmouseup(kf_inputbind_t id);
42
int kf_checkgamepadpress(kf_inputbind_t id);
43
int kf_checkgamepadrelease(kf_inputbind_t id);
44
int kf_checkgamepaddown(kf_inputbind_t id);
45
int kf_checkgamepadup(kf_inputbind_t id);
46
float kf_getgamepadaxis(kf_inputbind_t id);
47
48
int kf_checkinputpress(kf_inputbind_t id);
49
int kf_checkinputrelease(kf_inputbind_t id);
50
int kf_checkinputdown(kf_inputbind_t id);
51
int kf_checkinputup(kf_inputbind_t id);
52
53
···
1
#ifndef __kf_input__
2
#define __kf_input__
3
4
+
5
#include <keraforge/_header.h>
6
#include <raylib.h>
7
+
8
9
#define MOUSE_BUTTON_UNKNOWN ((MouseButton)-1)
10
#define GAMEPAD_AXIS_UNKNOWN ((GamepadAxis)-1)
···
13
typedef u8 kf_inputbind_t;
14
#define KF_INPUTBIND_NONE ((kf_inputbind_t)0)
15
16
+
17
+
/* Struct-of-Arrays for keybindings. */
18
struct _kf_inputbinds
19
{
20
kf_inputbind_t count; /* must start at 1. 0 is the `none` keybind. */
21
char *id[KF_INPUTBIND_MAX];
22
KeyboardKey key[KF_INPUTBIND_MAX];
23
+
KeyboardKey alt[KF_INPUTBIND_MAX];
24
MouseButton mouse[KF_INPUTBIND_MAX];
25
GamepadButton gamepad[KF_INPUTBIND_MAX];
26
GamepadAxis axis[KF_INPUTBIND_MAX];
27
};
28
29
+
30
/* Deadzone for gamepads. Default is 0.2f. */
31
extern f32 kf_deadzone;
32
+
/* Input binding struct-of-arrays. You should not mutate this directly (use kf_addinput). */
33
extern struct _kf_inputbinds kf_inputbinds;
34
+
35
36
/* Add a new input binding. */
37
+
kf_inputbind_t kf_addinput(char *id, KeyboardKey key, KeyboardKey alt, MouseButton mouse, GamepadButton gamepad, GamepadAxis axis);
38
/* Get an input's index by it's translation key. */
39
kf_inputbind_t kf_getinput(char *id);
40
41
+
/* Check if the given key was pressed this frame. */
42
int kf_checkkeypress(kf_inputbind_t id);
43
+
/* Check if the given key was released this frame. */
44
int kf_checkkeyrelease(kf_inputbind_t id);
45
+
/* Check if the given key is down. */
46
int kf_checkkeydown(kf_inputbind_t id);
47
+
/* Check if the given key is up. */
48
int kf_checkkeyup(kf_inputbind_t id);
49
+
/* Check if the given mouse button was pressed this frame. */
50
int kf_checkmousepress(kf_inputbind_t id);
51
+
/* Check if the given mouse button was released this frame. */
52
int kf_checkmouserelease(kf_inputbind_t id);
53
+
/* Check if the given mouse button is down. */
54
int kf_checkmousedown(kf_inputbind_t id);
55
+
/* Check if the given mouse button is up. */
56
int kf_checkmouseup(kf_inputbind_t id);
57
+
/* Check if the given gamepad button was pressed this frame. */
58
int kf_checkgamepadpress(kf_inputbind_t id);
59
+
/* Check if the given gamepad button was released this frame. */
60
int kf_checkgamepadrelease(kf_inputbind_t id);
61
+
/* Check if the given gamepad button is down. */
62
int kf_checkgamepaddown(kf_inputbind_t id);
63
+
/* Check if the given gamepad button is up. */
64
int kf_checkgamepadup(kf_inputbind_t id);
65
+
/* Get the given gamepad axis' value (-1 to +1). */
66
float kf_getgamepadaxis(kf_inputbind_t id);
67
68
+
/* Check if the given input binding was pressed this frame. */
69
int kf_checkinputpress(kf_inputbind_t id);
70
+
/* Check if the given input binding was released this frame. */
71
int kf_checkinputrelease(kf_inputbind_t id);
72
+
/* Check if the given input binding is down. */
73
int kf_checkinputdown(kf_inputbind_t id);
74
+
/* Check if the given input binding is up. */
75
int kf_checkinputup(kf_inputbind_t id);
76
77
+9
include/keraforge/math.h
+9
include/keraforge/math.h
···
1
#ifndef __kf_math__
2
#define __kf_math__
3
4
#include <keraforge/_header.h>
5
#include <raylib.h>
6
#include <raymath.h>
7
8
#define _kf_mathdef(x) \
9
x(i8); \
···
51
_kf_mathdef(x)
52
#undef x
53
54
enum kf_direction
55
{
56
kf_north,
···
59
kf_west,
60
};
61
62
enum kf_direction kf_rotatecw(enum kf_direction dir);
63
enum kf_direction kf_rotateccw(enum kf_direction dir);
64
struct kf_vec2(f32) kf_dtov2(enum kf_direction dir);
65
66
#endif
···
1
#ifndef __kf_math__
2
#define __kf_math__
3
4
+
5
#include <keraforge/_header.h>
6
#include <raylib.h>
7
#include <raymath.h>
8
+
9
10
#define _kf_mathdef(x) \
11
x(i8); \
···
53
_kf_mathdef(x)
54
#undef x
55
56
+
57
+
/* Represents a NESW direction. */
58
enum kf_direction
59
{
60
kf_north,
···
63
kf_west,
64
};
65
66
+
67
+
/* Rotate a direction clockwise. */
68
enum kf_direction kf_rotatecw(enum kf_direction dir);
69
+
/* Rotate a direction counterclockwise. */
70
enum kf_direction kf_rotateccw(enum kf_direction dir);
71
+
/* Get a vec2(f32) representing the direction. */
72
struct kf_vec2(f32) kf_dtov2(enum kf_direction dir);
73
+
74
75
#endif
+7
include/keraforge/sprites.h
+7
include/keraforge/sprites.h
···
1
#ifndef __kf_sprites__
2
#define __kf_sprites__
3
4
#include <keraforge/_header.h>
5
#include <raylib.h>
6
7
struct kf_spritesheet
8
{
9
Texture2D texture;
···
11
u32 nsprites;
12
};
13
14
struct kf_spritesheet kf_loadspritesheet(char *filename, int spritewidth, int spriteheight);
15
void kf_drawsprite(struct kf_spritesheet *sheet, f32 x, f32 y, int spritex, int spritey);
16
17
#endif
···
1
#ifndef __kf_sprites__
2
#define __kf_sprites__
3
4
+
5
#include <keraforge/_header.h>
6
#include <raylib.h>
7
8
+
9
+
/* Represents a single texture containing multiple sprites.
10
+
Can be used for animations or texture atlases. */
11
struct kf_spritesheet
12
{
13
Texture2D texture;
···
15
u32 nsprites;
16
};
17
18
+
19
+
/* Load a sprite sheet with the given sprite width/height. */
20
struct kf_spritesheet kf_loadspritesheet(char *filename, int spritewidth, int spriteheight);
21
+
/* Draw a single sprite from the sheet at the given coordinates. */
22
void kf_drawsprite(struct kf_spritesheet *sheet, f32 x, f32 y, int spritex, int spritey);
23
24
#endif
+28
-1
include/keraforge/ui.h
+28
-1
include/keraforge/ui.h
···
1
#ifndef __kf_ui__
2
#define __kf_ui__
3
4
#include <keraforge/input.h>
5
6
struct kf_uiconfig
7
{
8
kf_inputbind_t select, cancel, up, down;
9
-
char *fmt, *selectfmt;
10
int fontsize;
11
Color bg, fg;
12
int panelheight;
13
int xpadding, ypadding;
14
};
15
16
struct kf_uiconfig *kf_ui_getconfig(void);
17
18
int kf_ui_panel(char *title);
19
20
int kf_ui_choice(char *title, char **choices, int nchoices, int *choice);
21
int kf_ui_yesno(char *title, int *choice);
22
int kf_ui_textinput(char *title, char *text);
23
24
#endif
···
1
#ifndef __kf_ui__
2
#define __kf_ui__
3
4
+
5
#include <keraforge/input.h>
6
7
+
8
+
/* Holds global config settings for UIs. */
9
struct kf_uiconfig
10
{
11
+
/* Keybindings to navigate UIs. */
12
kf_inputbind_t select, cancel, up, down;
13
+
/* Format string for choices. */
14
+
char *fmt;
15
+
/* Format string for selected choices. */
16
+
char *selectfmt;
17
int fontsize;
18
Color bg, fg;
19
+
/* Height of the UI panel. */
20
int panelheight;
21
+
/* Padding for the panel. */
22
int xpadding, ypadding;
23
};
24
25
+
/* Get a pointer to the global UI config. */
26
struct kf_uiconfig *kf_ui_getconfig(void);
27
28
+
/* Draw a panel with the given title. Returns the Y position for the next line of text.
29
+
title: Title of the panel, drawn at the top of the panel. Must be null-terminated. */
30
int kf_ui_panel(char *title);
31
32
+
/* Present the player with a choice menu.
33
+
title: Panel title. Must be null-terminated.
34
+
choices: Array of possible choices. Must be null-terminated.
35
+
nchoices: Length of the array.
36
+
choice: Pointer to the selected choice. This will be mutated.
37
+
Returns: 1 if the user has made a choice, otherwise 0. */
38
int kf_ui_choice(char *title, char **choices, int nchoices, int *choice);
39
+
/* Present the player with a yes/no menu.
40
+
title: Panel title. Must be null-terminated.
41
+
choice: Pointer to the selected choice. This will be mutated. 1 is yes, 0 is no.
42
+
Returns: 1 if the user has made a choice, otherwise 0. */
43
int kf_ui_yesno(char *title, int *choice);
44
+
/* Present the player with a text input menu.
45
+
title: Panel title. Must be null-terminated.
46
+
text: The inputted text. If NULL, it will be malloc'd automatically.
47
+
If it needs to be grown, it will be realloc'd.
48
+
Returns: 1 if the user has made a choice, otherwise 0. */
49
int kf_ui_textinput(char *title, char *text);
50
51
#endif
+23
-3
include/keraforge/world.h
+23
-3
include/keraforge/world.h
···
1
#ifndef __kf_world__
2
#define __kf_world__
3
4
#include <keraforge/_header.h>
5
#include <raylib.h>
6
7
#define KF_TILEID_MAX UINT16_MAX
8
typedef u16 kf_tileid_t;
9
#define KF_TILE_SIZE_PX 16
10
11
struct kf_world
12
{
13
-
/* Never ever reorder `revision` to be after anything.
14
If you add something before it or move it then the
15
version checker will compare the first u32 in the
16
map's binary to the expected revision, which will
17
almost always be wrong. */
18
u32 revision;
19
u32 width;
20
u32 height;
21
kf_tileid_t map[];
22
};
23
24
struct _kf_tiles
25
{
26
kf_tileid_t count;
27
char *key[KF_TILEID_MAX];
28
-
Color color[KF_TILEID_MAX];
29
bool collide[KF_TILEID_MAX];
30
};
31
extern struct _kf_tiles kf_tiles;
32
33
/* Create a world using the given width and height.
···
41
kf_tileid_t *kf_world_gettile(struct kf_world *world, u32 x, u32 y);
42
43
/* Draw visible collision rectangles. */
44
-
struct kf_actor;
45
void kf_world_drawcolliders(struct kf_world *world, struct kf_actor *player, Camera2D camera);
46
47
/* Draw the part of the world visible to the given camera. */
···
1
#ifndef __kf_world__
2
#define __kf_world__
3
4
+
5
#include <keraforge/_header.h>
6
+
#include <keraforge/math.h>
7
#include <raylib.h>
8
9
+
10
#define KF_TILEID_MAX UINT16_MAX
11
typedef u16 kf_tileid_t;
12
#define KF_TILE_SIZE_PX 16
13
14
+
15
+
struct kf_actor; /* Forward declaration */
16
+
17
+
18
+
/* Represents a world (or a subworld, often called "rooms"). */
19
struct kf_world
20
{
21
+
/* Marks the version of this map, used for migrating from one engine version to another.
22
+
Never ever reorder `revision` to be after anything.
23
If you add something before it or move it then the
24
version checker will compare the first u32 in the
25
map's binary to the expected revision, which will
26
almost always be wrong. */
27
u32 revision;
28
+
/* Width of the map. */
29
u32 width;
30
+
/* Height of the map. */
31
u32 height;
32
+
/* Array of tiles in the map. Use kf_gettile to get a tile using an X/Y position. */
33
kf_tileid_t map[];
34
};
35
36
+
/* Struct-of-arrays for tiles. See: kf_tiles */
37
struct _kf_tiles
38
{
39
kf_tileid_t count;
40
+
/* Translation key of the tile. */
41
char *key[KF_TILEID_MAX];
42
+
/* The tile's colour on a world map. */
43
+
Color mapcol[KF_TILEID_MAX];
44
+
/* The spritesheet this tile's sprite belongs to. */
45
+
struct kf_spritesheet *sheet[KF_TILEID_MAX];
46
+
/* Spritesheet coords. */
47
+
struct kf_vec2(u32) sprite[KF_TILEID_MAX];
48
+
/* Whether or not this tile has collision. */
49
bool collide[KF_TILEID_MAX];
50
};
51
+
/* Struct-of-arrays for tiles. */
52
extern struct _kf_tiles kf_tiles;
53
54
/* Create a world using the given width and height.
···
62
kf_tileid_t *kf_world_gettile(struct kf_world *world, u32 x, u32 y);
63
64
/* Draw visible collision rectangles. */
65
void kf_world_drawcolliders(struct kf_world *world, struct kf_actor *player, Camera2D camera);
66
67
/* Draw the part of the world visible to the given camera. */
+1
src/actor.c
+1
src/actor.c
+1
src/fs.c
+1
src/fs.c
+1
src/graphics.c
+1
src/graphics.c
+79
-15
src/input.c
+79
-15
src/input.c
···
3
#include <stdio.h>
4
#include <string.h>
5
6
f32 kf_deadzone = 0.2f;
7
8
struct _kf_inputbinds kf_inputbinds = {
9
.count = 1,
10
};
11
12
-
kf_inputbind_t kf_addinput(char *id, KeyboardKey key, MouseButton mouse, GamepadButton gamepad, GamepadAxis axis)
13
{
14
kf_inputbind_t i = kf_inputbinds.count;
15
if (i >= KF_INPUTBIND_MAX)
···
19
}
20
kf_inputbinds.count++;
21
22
-
printf("add keybind: %d: %s (k=%d m=%d g=%d x=%d)\n", i, id, key, mouse, gamepad, axis);
23
kf_inputbinds.id[i] = id;
24
kf_inputbinds.key[i] = key;
25
kf_inputbinds.mouse[i] = mouse;
26
kf_inputbinds.gamepad[i] = gamepad;
27
kf_inputbinds.axis[i] = axis;
···
42
return KF_INPUTBIND_NONE;
43
}
44
45
-
int kf_checkkeypress(kf_inputbind_t id) { return kf_inputbinds.key[id] != KEY_NULL && IsKeyPressed(kf_inputbinds.key[id]); }
46
-
int kf_checkkeyrelease(kf_inputbind_t id) { return kf_inputbinds.key[id] != KEY_NULL && IsKeyReleased(kf_inputbinds.key[id]); }
47
-
int kf_checkkeydown(kf_inputbind_t id) { return kf_inputbinds.key[id] != KEY_NULL && IsKeyDown(kf_inputbinds.key[id]); }
48
-
int kf_checkkeyup(kf_inputbind_t id) { return kf_inputbinds.key[id] != KEY_NULL && IsKeyUp(kf_inputbinds.key[id]); }
49
-
int kf_checkmousepress(kf_inputbind_t id) { return kf_inputbinds.mouse[id] != MOUSE_BUTTON_UNKNOWN && IsMouseButtonPressed(kf_inputbinds.mouse[id]); }
50
-
int kf_checkmouserelease(kf_inputbind_t id) { return kf_inputbinds.mouse[id] != MOUSE_BUTTON_UNKNOWN && IsMouseButtonReleased(kf_inputbinds.mouse[id]); }
51
-
int kf_checkmousedown(kf_inputbind_t id) { return kf_inputbinds.mouse[id] != MOUSE_BUTTON_UNKNOWN && IsMouseButtonDown(kf_inputbinds.mouse[id]); }
52
-
int kf_checkmouseup(kf_inputbind_t id) { return kf_inputbinds.mouse[id] != MOUSE_BUTTON_UNKNOWN && IsMouseButtonUp(kf_inputbinds.mouse[id]); }
53
-
int kf_checkgamepadpress(kf_inputbind_t id) { return kf_inputbinds.gamepad[id] != GAMEPAD_BUTTON_UNKNOWN && IsGamepadButtonPressed(0, kf_inputbinds.gamepad[id]); }
54
-
int kf_checkgamepadrelease(kf_inputbind_t id) { return kf_inputbinds.gamepad[id] != GAMEPAD_BUTTON_UNKNOWN && IsGamepadButtonReleased(0, kf_inputbinds.gamepad[id]); }
55
-
int kf_checkgamepaddown(kf_inputbind_t id) { return kf_inputbinds.gamepad[id] != GAMEPAD_BUTTON_UNKNOWN && IsGamepadButtonDown(0, kf_inputbinds.gamepad[id]); }
56
-
int kf_checkgamepadup(kf_inputbind_t id) { return kf_inputbinds.gamepad[id] != GAMEPAD_BUTTON_UNKNOWN && IsGamepadButtonUp(0, kf_inputbinds.gamepad[id]); }
57
-
float kf_getgamepadaxis(kf_inputbind_t id) { return kf_inputbinds.axis[id] != GAMEPAD_AXIS_UNKNOWN ? GetGamepadAxisMovement(0, kf_inputbinds.gamepad[id]) : 0; }
58
59
int kf_checkinputpress(kf_inputbind_t id)
60
{
···
3
#include <stdio.h>
4
#include <string.h>
5
6
+
7
f32 kf_deadzone = 0.2f;
8
9
struct _kf_inputbinds kf_inputbinds = {
10
.count = 1,
11
};
12
13
+
14
+
kf_inputbind_t kf_addinput(char *id, KeyboardKey key, KeyboardKey alt, MouseButton mouse, GamepadButton gamepad, GamepadAxis axis)
15
{
16
kf_inputbind_t i = kf_inputbinds.count;
17
if (i >= KF_INPUTBIND_MAX)
···
21
}
22
kf_inputbinds.count++;
23
24
+
printf("add keybind: %d: %s (k=%d a=%d m=%d g=%d x=%d)\n", i, id, key, alt, mouse, gamepad, axis);
25
kf_inputbinds.id[i] = id;
26
kf_inputbinds.key[i] = key;
27
+
kf_inputbinds.alt[i] = alt;
28
kf_inputbinds.mouse[i] = mouse;
29
kf_inputbinds.gamepad[i] = gamepad;
30
kf_inputbinds.axis[i] = axis;
···
45
return KF_INPUTBIND_NONE;
46
}
47
48
+
49
+
int kf_checkkeypress(kf_inputbind_t id)
50
+
{
51
+
return
52
+
(kf_inputbinds.key[id] != KEY_NULL && IsKeyPressed(kf_inputbinds.key[id])) ||
53
+
(kf_inputbinds.alt[id] != KEY_NULL && IsKeyPressed(kf_inputbinds.alt[id]));
54
+
}
55
+
56
+
int kf_checkkeyrelease(kf_inputbind_t id)
57
+
{
58
+
return
59
+
(kf_inputbinds.key[id] != KEY_NULL && IsKeyReleased(kf_inputbinds.key[id])) ||
60
+
(kf_inputbinds.alt[id] != KEY_NULL && IsKeyReleased(kf_inputbinds.alt[id]));
61
+
}
62
+
63
+
int kf_checkkeydown(kf_inputbind_t id)
64
+
{
65
+
return
66
+
(kf_inputbinds.key[id] != KEY_NULL && IsKeyDown(kf_inputbinds.key[id])) ||
67
+
(kf_inputbinds.alt[id] != KEY_NULL && IsKeyDown(kf_inputbinds.alt[id]));
68
+
}
69
+
70
+
int kf_checkkeyup(kf_inputbind_t id)
71
+
{
72
+
return
73
+
(kf_inputbinds.key[id] != KEY_NULL && IsKeyUp(kf_inputbinds.key[id])) ||
74
+
(kf_inputbinds.alt[id] != KEY_NULL && IsKeyUp(kf_inputbinds.alt[id]));
75
+
}
76
+
77
+
int kf_checkmousepress(kf_inputbind_t id)
78
+
{
79
+
return kf_inputbinds.mouse[id] != MOUSE_BUTTON_UNKNOWN && IsMouseButtonPressed(kf_inputbinds.mouse[id]);
80
+
}
81
+
82
+
int kf_checkmouserelease(kf_inputbind_t id)
83
+
{
84
+
return kf_inputbinds.mouse[id] != MOUSE_BUTTON_UNKNOWN && IsMouseButtonReleased(kf_inputbinds.mouse[id]);
85
+
}
86
+
87
+
int kf_checkmousedown(kf_inputbind_t id)
88
+
{
89
+
return kf_inputbinds.mouse[id] != MOUSE_BUTTON_UNKNOWN && IsMouseButtonDown(kf_inputbinds.mouse[id]);
90
+
}
91
+
92
+
int kf_checkmouseup(kf_inputbind_t id)
93
+
{
94
+
return kf_inputbinds.mouse[id] != MOUSE_BUTTON_UNKNOWN && IsMouseButtonUp(kf_inputbinds.mouse[id]);
95
+
}
96
+
97
+
int kf_checkgamepadpress(kf_inputbind_t id)
98
+
{
99
+
return kf_inputbinds.gamepad[id] != GAMEPAD_BUTTON_UNKNOWN && IsGamepadButtonPressed(0, kf_inputbinds.gamepad[id]);
100
+
}
101
+
102
+
int kf_checkgamepadrelease(kf_inputbind_t id)
103
+
{
104
+
return kf_inputbinds.gamepad[id] != GAMEPAD_BUTTON_UNKNOWN && IsGamepadButtonReleased(0, kf_inputbinds.gamepad[id]);
105
+
}
106
+
107
+
int kf_checkgamepaddown(kf_inputbind_t id)
108
+
{
109
+
return kf_inputbinds.gamepad[id] != GAMEPAD_BUTTON_UNKNOWN && IsGamepadButtonDown(0, kf_inputbinds.gamepad[id]);
110
+
}
111
+
112
+
int kf_checkgamepadup(kf_inputbind_t id)
113
+
{
114
+
return kf_inputbinds.gamepad[id] != GAMEPAD_BUTTON_UNKNOWN && IsGamepadButtonUp(0, kf_inputbinds.gamepad[id]);
115
+
}
116
+
117
+
float kf_getgamepadaxis(kf_inputbind_t id)
118
+
{
119
+
return kf_inputbinds.axis[id] != GAMEPAD_AXIS_UNKNOWN ? GetGamepadAxisMovement(0, kf_inputbinds.gamepad[id]) : 0;
120
+
}
121
+
122
123
int kf_checkinputpress(kf_inputbind_t id)
124
{
+55
-35
src/main.c
+55
-35
src/main.c
···
5
#include <stdio.h>
6
#include <stdlib.h>
7
8
static Camera2D cam;
9
static struct kf_vec2(u32) select = { 0, 0 };
10
static int selected_tile = 0;
11
-
12
-
enum {
13
menu_none,
14
menu_palette,
15
menu_escape
···
33
inputbind_zoom_out
34
;
35
36
-
static void loadbinds()
37
{
38
-
inputbind_move_up = kf_addinput("move_up", KEY_W, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_Y);
39
-
inputbind_move_down = kf_addinput("move_down", KEY_S, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_Y);
40
-
inputbind_move_left = kf_addinput("move_left", KEY_A, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_X);
41
-
inputbind_move_right = kf_addinput("move_right", KEY_D, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_X);
42
43
-
inputbind_ui_up = kf_addinput("ui_up", KEY_W, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_UP, GAMEPAD_AXIS_UNKNOWN);
44
-
inputbind_ui_down = kf_addinput("ui_down", KEY_S, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_DOWN, GAMEPAD_AXIS_UNKNOWN);
45
-
inputbind_ui_left = kf_addinput("ui_left", KEY_A, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_LEFT, GAMEPAD_AXIS_UNKNOWN);
46
-
inputbind_ui_right = kf_addinput("ui_right", KEY_D, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
47
48
-
inputbind_select = kf_addinput("select", KEY_F, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_DOWN, GAMEPAD_AXIS_UNKNOWN);
49
-
inputbind_cancel = kf_addinput("cancel", KEY_Q, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
50
51
-
inputbind_pause = kf_addinput("pause", KEY_ESCAPE, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_MIDDLE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
52
-
inputbind_palette = kf_addinput("palette", KEY_TAB, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_UP, GAMEPAD_AXIS_UNKNOWN);
53
54
-
inputbind_zoom_reset = kf_addinput("zoom_reset", KEY_ZERO, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
55
-
inputbind_zoom_in = kf_addinput("zoom_in", KEY_EQUAL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
56
-
inputbind_zoom_out = kf_addinput("zoom_out", KEY_MINUS, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
57
}
58
59
-
static void _player_tick_move(struct kf_actor *self)
60
{
61
struct kf_vec2(f32) v = {0, 0};
62
···
105
kf_actor_addforce(self, v);
106
}
107
108
-
static void _player_tick(struct kf_world *world, struct kf_actor *self)
109
{
110
if (menu == menu_none)
111
_player_tick_move(self);
···
113
kf_actor_move(world, self, kf_dts);
114
}
115
116
-
static void _player_draw(struct kf_world *world, struct kf_actor *self)
117
{
118
(void)world;
119
-
// DrawRectangleLines(self->pos.x + self->size.x/2 + self->sizeoffset.x, self->pos.y + self->size.y/2 + self->sizeoffset.y, self->size.x, self->size.y, RED);
120
kf_actor_draw(self);
121
122
cam.target.x = self->pos.x + (self->size.x / 2);
123
cam.target.y = self->pos.y + (self->size.y / 2);
124
}
125
126
int main(int argc, const char *argv[])
127
{
···
136
loadbinds();
137
138
kf_tiles.key[0] = "grass";
139
-
kf_tiles.color[0] = GREEN;
140
kf_tiles.key[1] = "dirt";
141
-
kf_tiles.color[1] = BROWN;
142
kf_tiles.key[2] = "stone";
143
-
kf_tiles.color[2] = GRAY;
144
kf_tiles.collide[2] = true;
145
kf_tiles.count = 3;
146
···
212
select.y = v.y / KF_TILE_SIZE_PX;
213
214
if (kf_checkinputpress(inputbind_palette))
215
-
menu = menu_palette;
216
-
else if (kf_checkinputpress(inputbind_pause) && menu == menu_none)
217
-
menu = menu_escape;
218
else if (kf_checkinputpress(inputbind_zoom_reset))
219
cam.zoom = 2;
220
else if (kf_checkinputpress(inputbind_zoom_in) && cam.zoom < 3.50f)
···
227
228
BeginMode2D(cam);
229
kf_world_draw(world, cam);
230
-
kf_world_drawcolliders(world, player, cam);
231
if (select.x < world->width && select.y < world->height)
232
{
233
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
···
240
player->draw(world, player);
241
EndMode2D();
242
243
-
switch (menu)
244
{
245
case menu_none:
246
break;
247
case menu_palette:
248
if (kf_ui_choice("Select tile", &kf_tiles.key[0], kf_tiles.count, &selected_tile))
249
-
menu = menu_none;
250
break;
251
case menu_escape:
252
-
{
253
-
static int result = 0;
254
if (kf_ui_yesno("Exit game?", &result))
255
{
256
menu = menu_none;
257
-
if (result == 0)
258
running = 0;
259
-
result = 0;
260
}
261
break;
262
}
263
}
264
···
5
#include <stdio.h>
6
#include <stdlib.h>
7
8
+
9
static Camera2D cam;
10
static struct kf_vec2(u32) select = { 0, 0 };
11
static int selected_tile = 0;
12
+
static bool selected_menu_this_frame = false;
13
+
static enum {
14
menu_none,
15
menu_palette,
16
menu_escape
···
34
inputbind_zoom_out
35
;
36
37
+
38
+
static
39
+
void loadbinds()
40
{
41
+
inputbind_move_up = kf_addinput("move_up", KEY_W, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_Y);
42
+
inputbind_move_down = kf_addinput("move_down", KEY_S, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_Y);
43
+
inputbind_move_left = kf_addinput("move_left", KEY_A, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_X);
44
+
inputbind_move_right = kf_addinput("move_right", KEY_D, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_X);
45
46
+
inputbind_ui_up = kf_addinput("ui_up", KEY_W, KEY_UP, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_UP, GAMEPAD_AXIS_UNKNOWN);
47
+
inputbind_ui_down = kf_addinput("ui_down", KEY_S, KEY_DOWN, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_DOWN, GAMEPAD_AXIS_UNKNOWN);
48
+
inputbind_ui_left = kf_addinput("ui_left", KEY_A, KEY_LEFT, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_LEFT, GAMEPAD_AXIS_UNKNOWN);
49
+
inputbind_ui_right = kf_addinput("ui_right", KEY_D, KEY_RIGHT, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
50
51
+
inputbind_select = kf_addinput("select", KEY_E, KEY_ENTER, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_DOWN, GAMEPAD_AXIS_UNKNOWN);
52
+
inputbind_cancel = kf_addinput("cancel", KEY_Q, KEY_ESCAPE, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
53
54
+
inputbind_pause = kf_addinput("pause", KEY_ESCAPE, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_MIDDLE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
55
+
inputbind_palette = kf_addinput("palette", KEY_TAB, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_UP, GAMEPAD_AXIS_UNKNOWN);
56
57
+
inputbind_zoom_reset = kf_addinput("zoom_reset", KEY_ZERO, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
58
+
inputbind_zoom_in = kf_addinput("zoom_in", KEY_EQUAL, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
59
+
inputbind_zoom_out = kf_addinput("zoom_out", KEY_MINUS, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
60
}
61
62
+
static
63
+
void setmenu(int m)
64
+
{
65
+
menu = m;
66
+
selected_menu_this_frame = true;
67
+
}
68
+
69
+
static
70
+
void _player_tick_move(struct kf_actor *self)
71
{
72
struct kf_vec2(f32) v = {0, 0};
73
···
116
kf_actor_addforce(self, v);
117
}
118
119
+
static
120
+
void _player_tick(struct kf_world *world, struct kf_actor *self)
121
{
122
if (menu == menu_none)
123
_player_tick_move(self);
···
125
kf_actor_move(world, self, kf_dts);
126
}
127
128
+
static
129
+
void _player_draw(struct kf_world *world, struct kf_actor *self)
130
{
131
(void)world;
132
kf_actor_draw(self);
133
134
cam.target.x = self->pos.x + (self->size.x / 2);
135
cam.target.y = self->pos.y + (self->size.y / 2);
136
}
137
+
138
139
int main(int argc, const char *argv[])
140
{
···
149
loadbinds();
150
151
kf_tiles.key[0] = "grass";
152
+
kf_tiles.mapcol[0] = GREEN;
153
kf_tiles.key[1] = "dirt";
154
+
kf_tiles.mapcol[1] = BROWN;
155
kf_tiles.key[2] = "stone";
156
+
kf_tiles.mapcol[2] = GRAY;
157
kf_tiles.collide[2] = true;
158
kf_tiles.count = 3;
159
···
225
select.y = v.y / KF_TILE_SIZE_PX;
226
227
if (kf_checkinputpress(inputbind_palette))
228
+
setmenu(menu_palette);
229
+
else if (kf_checkinputpress(inputbind_cancel) && menu == menu_none)
230
+
setmenu(menu_escape);
231
else if (kf_checkinputpress(inputbind_zoom_reset))
232
cam.zoom = 2;
233
else if (kf_checkinputpress(inputbind_zoom_in) && cam.zoom < 3.50f)
···
240
241
BeginMode2D(cam);
242
kf_world_draw(world, cam);
243
+
// kf_world_drawcolliders(world, player, cam);
244
if (select.x < world->width && select.y < world->height)
245
{
246
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
···
253
player->draw(world, player);
254
EndMode2D();
255
256
+
if (selected_menu_this_frame)
257
+
{
258
+
selected_menu_this_frame = false;
259
+
}
260
+
else
261
{
262
+
switch (menu)
263
+
{
264
case menu_none:
265
break;
266
case menu_palette:
267
if (kf_ui_choice("Select tile", &kf_tiles.key[0], kf_tiles.count, &selected_tile))
268
+
setmenu(menu_none);
269
break;
270
case menu_escape:
271
+
{
272
+
static int result = 1;
273
if (kf_ui_yesno("Exit game?", &result))
274
{
275
menu = menu_none;
276
+
if (result)
277
running = 0;
278
+
result = 1;
279
}
280
break;
281
+
}
282
}
283
}
284
+4
-1
src/math.c
+4
-1
src/math.c
+1
src/sprites.c
+1
src/sprites.c
+6
-3
src/ui.c
+6
-3
src/ui.c
···
1
#include <keraforge.h>
2
#include <raylib.h>
3
4
-
static struct kf_uiconfig _kf_uiconfig = {
5
.select = KF_INPUTBIND_NONE,
6
.cancel = KF_INPUTBIND_NONE,
7
.up = KF_INPUTBIND_NONE,
···
15
.xpadding = 8,
16
.ypadding = 16,
17
};
18
19
struct kf_uiconfig *kf_ui_getconfig(void)
20
{
···
64
65
if (kf_checkinputpress(_kf_uiconfig.select) || kf_checkinputpress(_kf_uiconfig.cancel))
66
return 1;
67
-
else if (kf_checkinputpress(_kf_uiconfig.down) && *choice < nchoices)
68
(*choice)++;
69
else if (kf_checkinputpress(_kf_uiconfig.up) && *choice > 0)
70
(*choice)--;
···
75
int kf_ui_yesno(char *title, int *choice)
76
{
77
static char *yesno[] = { "yes", "no" };
78
-
return kf_ui_choice(title, yesno, 2, choice);
79
}
80
81
int kf_ui_textinput(char *title, char *text);
···
1
#include <keraforge.h>
2
#include <raylib.h>
3
4
+
5
+
static
6
+
struct kf_uiconfig _kf_uiconfig = {
7
.select = KF_INPUTBIND_NONE,
8
.cancel = KF_INPUTBIND_NONE,
9
.up = KF_INPUTBIND_NONE,
···
17
.xpadding = 8,
18
.ypadding = 16,
19
};
20
+
21
22
struct kf_uiconfig *kf_ui_getconfig(void)
23
{
···
67
68
if (kf_checkinputpress(_kf_uiconfig.select) || kf_checkinputpress(_kf_uiconfig.cancel))
69
return 1;
70
+
else if (kf_checkinputpress(_kf_uiconfig.down) && *choice < nchoices - 1)
71
(*choice)++;
72
else if (kf_checkinputpress(_kf_uiconfig.up) && *choice > 0)
73
(*choice)--;
···
78
int kf_ui_yesno(char *title, int *choice)
79
{
80
static char *yesno[] = { "yes", "no" };
81
+
return !kf_ui_choice(title, yesno, 2, choice);
82
}
83
84
int kf_ui_textinput(char *title, char *text);
+3
-1
src/world.c
+3
-1
src/world.c
···
4
#include <string.h>
5
#include <math.h>
6
7
struct _kf_tiles kf_tiles = {0};
8
9
struct kf_world *kf_world_new(u32 width, u32 height, kf_tileid_t fill)
10
{
···
93
(int)y * KF_TILE_SIZE_PX,
94
KF_TILE_SIZE_PX,
95
KF_TILE_SIZE_PX,
96
-
kf_tiles.color[*tile]
97
);
98
tile++; /* shift tile pointer to the right */
99
}
···
4
#include <string.h>
5
#include <math.h>
6
7
+
8
struct _kf_tiles kf_tiles = {0};
9
+
10
11
struct kf_world *kf_world_new(u32 width, u32 height, kf_tileid_t fill)
12
{
···
95
(int)y * KF_TILE_SIZE_PX,
96
KF_TILE_SIZE_PX,
97
KF_TILE_SIZE_PX,
98
+
kf_tiles.mapcol[*tile]
99
);
100
tile++; /* shift tile pointer to the right */
101
}