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