+3
include/keraforge.h
+3
include/keraforge.h
···
7
7
#include <keraforge/log.h>
8
8
9
9
#include <keraforge/actor.h>
10
+
#include <keraforge/editor.h>
10
11
#include <keraforge/error.h>
11
12
#include <keraforge/fs.h>
12
13
#include <keraforge/graphics.h>
13
14
#include <keraforge/input.h>
15
+
#include <keraforge/inputbinds.h>
14
16
#include <keraforge/math.h>
17
+
#include <keraforge/player.h>
15
18
#include <keraforge/sprites.h>
16
19
#include <keraforge/state.h>
17
20
#include <keraforge/ui.h>
+2
-2
include/keraforge/actor.h
+2
-2
include/keraforge/actor.h
···
38
38
/* If the actor is running. This will not increase their speed, you are expected to yourself. */
39
39
bool running;
40
40
/* Called every frame to update the actor. Don't forget about deltatime (kf_dts, kf_dtms)! */
41
-
void (*tick)(struct kf_world *world, struct kf_actor *self);
41
+
void (*tick)(struct kf_actor *self);
42
42
/* Called every frame to render the actor. */
43
-
void (*draw)(struct kf_world *world, struct kf_actor *self);
43
+
void (*draw)(struct kf_actor *self);
44
44
};
45
45
46
46
+22
include/keraforge/editor.h
+22
include/keraforge/editor.h
···
1
+
#ifndef __kf_editor__
2
+
#define __kf_editor__
3
+
4
+
5
+
#include <keraforge/_header.h>
6
+
#include <keraforge/world.h>
7
+
8
+
9
+
/* State for the world editor */
10
+
struct kf_editor
11
+
{
12
+
/* The tile that the player is "holding." */
13
+
kf_tileid_t selected_tile;
14
+
/* If the world has been changed or not. */
15
+
bool dirty;
16
+
};
17
+
18
+
extern struct kf_modal kf_modal_edit;
19
+
extern struct kf_modal kf_menu_palette;
20
+
21
+
22
+
#endif
+69
include/keraforge/graphics.h
+69
include/keraforge/graphics.h
···
3
3
4
4
5
5
#include <keraforge/_header.h>
6
+
#include <keraforge/math.h>
7
+
#include <raylib.h>
6
8
7
9
10
+
/* Represents either a model or a menu. */
11
+
struct kf_modal
12
+
{
13
+
char *name;
14
+
void (*exit)(void);
15
+
void (*init)(void);
16
+
void (*update)(void);
17
+
void (*render_world)(void);
18
+
void (*render_ui)(void);
19
+
void *data;
20
+
};
21
+
22
+
/* Stores data about the window and graphics. None of this data is stored between saves/loads. */
23
+
struct kf_window
24
+
{
25
+
/* World camera. */
26
+
Camera2D cam;
27
+
/* Target FPS. Do not mutate this yourself, use kf_settargetfps(). */
28
+
int target_fps;
29
+
/* Indicates whether or not a window is open. */
30
+
bool running;
31
+
32
+
/* Pointer to the current state. */
33
+
struct kf_state *state;
34
+
/* Pointer to the current room. */
35
+
struct kf_world *room;
36
+
/* Pointer to the current player. */
37
+
struct kf_actor *player;
38
+
39
+
/* X,Y coords of the selected tile */
40
+
struct kf_vec2(u32) select;
41
+
42
+
/* Current modal. Do not mutate this yourself, use kf_setmodal(). */
43
+
struct kf_modal *modal;
44
+
/* Current menu. Do not mutate this yourself, use kf_setmenu(). */
45
+
struct kf_modal *menu;
46
+
47
+
/* Font used for kf_drawtext functions. */
48
+
Font font;
49
+
/* Base font size to use. */
50
+
int fontsize;
51
+
};
52
+
53
+
/* Global window instance. */
54
+
extern struct kf_window kf_window;
8
55
/* Number of frames since the game opened.
9
56
Not consistent enough for precise timing! Use deltatime (kf_dts/kf_dtms) instead. */
10
57
extern u64 kf_frame;
···
14
61
extern f32 kf_dtms;
15
62
/* Deltatime in seconds. */
16
63
extern f32 kf_dts;
64
+
65
+
66
+
int kf_measuretext(int size, char *text);
67
+
void kf_drawtext(Color c, int x, int y, int size, char *text);
68
+
void kf_drawtextshadowed(Color c, int x, int y, int size, char *text);
69
+
70
+
71
+
/* Open a window via Raylib. This should only be called once! */
72
+
void kf_openwindow(char *title);
73
+
/* Start the render loop. */
74
+
void kf_startwindow(void);
75
+
/* Close the window. */
76
+
void kf_closewindow(void);
77
+
/* Set the target FPS. Prefer this over manually setting kf_window.target_fps. */
78
+
void kf_settargetfps(int fps);
79
+
/* Set the current modal. */
80
+
void kf_setmodal(struct kf_modal *modal);
81
+
/* Set the current menu. */
82
+
void kf_setmenu(struct kf_modal *menu);
83
+
84
+
/* Default modal. */
85
+
extern struct kf_modal kf_modal_play;
17
86
18
87
19
88
#endif
+39
include/keraforge/inputbinds.h
+39
include/keraforge/inputbinds.h
···
1
+
#ifndef __kf_inputbinds__
2
+
#define __kf_inputbinds__
3
+
4
+
5
+
#include <keraforge/_header.h>
6
+
#include <keraforge/input.h>
7
+
8
+
9
+
/* Keraforge default keybinds. */
10
+
extern kf_inputbind_t
11
+
kf_inputbind_move_up,
12
+
kf_inputbind_move_down,
13
+
kf_inputbind_move_left,
14
+
kf_inputbind_move_right,
15
+
kf_inputbind_run,
16
+
17
+
kf_inputbind_ui_up,
18
+
kf_inputbind_ui_down,
19
+
kf_inputbind_ui_left,
20
+
kf_inputbind_ui_right,
21
+
kf_inputbind_select,
22
+
kf_inputbind_cancel,
23
+
24
+
kf_inputbind_pause,
25
+
kf_inputbind_palette,
26
+
27
+
kf_inputbind_zoom_reset,
28
+
kf_inputbind_zoom_in,
29
+
kf_inputbind_zoom_out,
30
+
31
+
kf_inputbind_toggle_fps_limit,
32
+
kf_inputbind_toggle_editor
33
+
;
34
+
35
+
36
+
void kf_loaddefaultbinds(void);
37
+
38
+
39
+
#endif
+13
include/keraforge/player.h
+13
include/keraforge/player.h
+5
-2
include/keraforge/ui.h
+5
-2
include/keraforge/ui.h
···
21
21
/* Padding for the panel. */
22
22
int xpadding, ypadding;
23
23
};
24
+
/* Global UI config. */
25
+
extern struct kf_uiconfig kf_uiconfig;
24
26
25
-
/* Get a pointer to the global UI config. */
26
-
struct kf_uiconfig *kf_ui_getconfig(void);
27
+
/* Performs non-compile-time initialization for kf_uiconfig.
28
+
This is called automatically by kf_openwindow. */
29
+
void kf_ui_init(void);
27
30
28
31
/* Draw a panel with the given title. Returns the Y position for the next line of text.
29
32
title: Title of the panel, drawn at the top of the panel. Must be null-terminated. */
+143
src/editor.c
+143
src/editor.c
···
1
+
#include "keraforge/editor.h"
2
+
#include "keraforge/graphics.h"
3
+
#include "keraforge/world.h"
4
+
#include <keraforge.h>
5
+
6
+
7
+
static
8
+
void _kf_modal_edit_init(void)
9
+
{
10
+
struct kf_editor *editor = malloc(sizeof(struct kf_editor));
11
+
editor->selected_tile = 0;
12
+
editor->dirty = false;
13
+
kf_window.modal->data = editor;
14
+
}
15
+
16
+
static
17
+
void _kf_modal_edit_exit(void)
18
+
{
19
+
bool d = ((struct kf_editor *)kf_window.modal->data)->dirty;
20
+
21
+
kf_logdbg("exiting editor, world is %s", d ? "dirty" : "not dirty");
22
+
23
+
if (d)
24
+
kf_world_save(kf_window.room, true);
25
+
26
+
free(kf_window.modal->data);
27
+
kf_window.modal->data = NULL;
28
+
}
29
+
30
+
static
31
+
void _kf_modal_edit_update(void)
32
+
{
33
+
/* Inherit from kf_modal_play. */
34
+
kf_modal_play.update();
35
+
36
+
if (kf_checkinputpress(kf_inputbind_palette) && kf_window.modal == &kf_modal_edit)
37
+
kf_setmenu(&kf_menu_palette);
38
+
}
39
+
40
+
static
41
+
void _kf_modal_edit_render_world(void)
42
+
{
43
+
/* Inherit from kf_modal_play. */
44
+
kf_modal_play.render_world();
45
+
46
+
if (kf_window.menu)
47
+
return;
48
+
49
+
struct kf_vec2(u32) select = kf_window.select;
50
+
51
+
if (select.x >= kf_window.room->width || select.y >= kf_window.room->height)
52
+
return;
53
+
54
+
struct kf_editor *data = (struct kf_editor *)kf_window.modal->data;
55
+
struct kf_tile *t = kf_world_gettile(kf_window.room, select.x, select.y);
56
+
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
57
+
{
58
+
t->id = data->selected_tile;
59
+
data->dirty = true;
60
+
kf_world_updatetile(kf_window.room, select.x, select.y, true);
61
+
}
62
+
else if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
63
+
{
64
+
t->subid = data->selected_tile;
65
+
data->dirty = true;
66
+
}
67
+
else if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE))
68
+
{
69
+
data->selected_tile = t->id;
70
+
}
71
+
72
+
DrawRectangleLines(select.x * KF_TILE_SIZE_PX, select.y * KF_TILE_SIZE_PX, KF_TILE_SIZE_PX, KF_TILE_SIZE_PX, WHITE);
73
+
char *text = (char *)TextFormat("%d [%d] (%d,%d)", t->id, t->data, select.x, select.y);
74
+
int s = kf_window.fontsize / kf_window.cam.zoom;
75
+
kf_drawtext(
76
+
BLACK,
77
+
select.x * KF_TILE_SIZE_PX,
78
+
select.y * KF_TILE_SIZE_PX - s,
79
+
s,
80
+
text
81
+
);
82
+
}
83
+
84
+
static
85
+
void _kf_modal_edit_render_ui()
86
+
{
87
+
/* Inherit from kf_modal_play. */
88
+
kf_modal_play.render_ui();
89
+
}
90
+
91
+
struct kf_modal kf_modal_edit = {
92
+
.name = "map editor",
93
+
.init = _kf_modal_edit_init,
94
+
.exit = _kf_modal_edit_exit,
95
+
.update = _kf_modal_edit_update,
96
+
.render_world = _kf_modal_edit_render_world,
97
+
.render_ui = _kf_modal_edit_render_ui,
98
+
.data = NULL,
99
+
};
100
+
101
+
102
+
static
103
+
void _kf_menu_palette_render_ui(void)
104
+
{
105
+
kf_tileid_t *selected = &((struct kf_editor *)kf_window.modal->data)->selected_tile;
106
+
107
+
int px = 80, py = 80;
108
+
DrawRectangle(px, py, 400, 400, BLACK);
109
+
kf_drawtextshadowed(WHITE, px + 10, py + 10, kf_window.fontsize, "tiles :3");
110
+
py += 40;
111
+
int x = 0, y = 0;
112
+
int s = KF_TILE_SIZE_PX * 2;
113
+
for (int i = 1 ; i <= kf_tiles.count ; i++)
114
+
{
115
+
Rectangle r = {px + x*s, py + y*s, s, s};
116
+
kf_drawsprite_wh(kf_tiles.sheet[i], r.x, r.y, r.width, r.height, kf_tiles.sprite[i].x + 0, kf_tiles.sprite[i].y + 3);
117
+
118
+
if (*selected == i)
119
+
DrawRectangleLinesEx(r, 1, GOLD);
120
+
121
+
if (CheckCollisionPointRec(GetMousePosition(), r))
122
+
{
123
+
DrawRectangleLinesEx(r, 1, WHITE);
124
+
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
125
+
*selected = i;
126
+
}
127
+
128
+
x += 1;
129
+
if (x >= 8)
130
+
{
131
+
x = 0;
132
+
y++;
133
+
}
134
+
}
135
+
136
+
if (kf_checkinputpress(kf_inputbind_cancel))
137
+
kf_setmenu(NULL);
138
+
};
139
+
140
+
struct kf_modal kf_menu_palette = {
141
+
.name = "tile palette",
142
+
.render_ui = _kf_menu_palette_render_ui,
143
+
};
+233
src/graphics.c
+233
src/graphics.c
···
1
1
#include <keraforge.h>
2
+
#include <raylib.h>
2
3
3
4
4
5
u64 kf_frame = 0;
5
6
f64 kf_s = 0;
6
7
f32 kf_dtms = 0;
7
8
f32 kf_dts = 0;
9
+
struct kf_window kf_window = {0};
10
+
11
+
12
+
int kf_measuretext(int size, char *text)
13
+
{
14
+
return MeasureTextEx(kf_window.font, text, size, 2).x;
15
+
}
16
+
17
+
void kf_drawtext(Color c, int x, int y, int size, char *text)
18
+
{
19
+
DrawTextEx(kf_window.font, text, (Vector2){x, y}, size, 2, c);
20
+
}
21
+
22
+
void kf_drawtextshadowed(Color c, int x, int y, int size, char *text)
23
+
{
24
+
kf_drawtext(BLACK, x+1, y+1, size, text);
25
+
kf_drawtext(c, x, y, size, text);
26
+
}
27
+
28
+
29
+
void kf_openwindow(char *title)
30
+
{
31
+
kf_window.target_fps = 60;
32
+
33
+
SetTraceLogLevel(LOG_WARNING);
34
+
InitWindow(800, 600, title);
35
+
SetTargetFPS(kf_window.target_fps);
36
+
SetExitKey(KEY_NULL);
37
+
38
+
kf_window.font = GetFontDefault();
39
+
kf_window.fontsize = 20;
40
+
41
+
kf_loaddefaultbinds();
42
+
kf_ui_init();
43
+
44
+
struct kf_state *state = NULL;
45
+
int is_new_state = kf_state_load(&state);
46
+
kf_window.state = state;
47
+
48
+
struct kf_world *world = NULL;
49
+
kf_world_load(&world, true);
50
+
kf_window.room = world;
51
+
52
+
struct kf_actor *player = kf_actor_new(kf_actor_loadspritesheet("data/res/img/char/template.png"), 10, 10, true);
53
+
player->sizeoffset.y = 6;
54
+
player->tick = kf_player_tick;
55
+
player->draw = kf_player_draw;
56
+
player->controlled = true;
57
+
if (is_new_state) /* place the player in the centre of the room */
58
+
{
59
+
state->player.pos.x = world->width * KF_TILE_SIZE_PX / 2.0f;
60
+
state->player.pos.y = world->width * KF_TILE_SIZE_PX / 2.0f;
61
+
}
62
+
player->pos.x = state->player.pos.x;
63
+
player->pos.y = state->player.pos.y;
64
+
kf_window.player = player;
65
+
66
+
kf_window.cam.target.x = player->pos.x + (player->size.x / 2);
67
+
kf_window.cam.target.y = player->pos.y + (player->size.y / 2);
68
+
kf_window.cam.zoom = 2;
69
+
70
+
kf_setmodal(&kf_modal_play);
71
+
}
72
+
73
+
void kf_startwindow(void)
74
+
{
75
+
kf_window.running = 1;
76
+
kf_window.cam.offset.x = GetScreenWidth() / 2.0f;
77
+
kf_window.cam.offset.y = GetScreenHeight() / 2.0f;
78
+
while (!WindowShouldClose() && kf_window.running)
79
+
{
80
+
if (IsWindowResized())
81
+
{
82
+
kf_window.cam.offset.x = GetScreenWidth() / 2.0f;
83
+
kf_window.cam.offset.y = GetScreenHeight() / 2.0f;
84
+
}
85
+
86
+
if (kf_window.modal && kf_window.modal->render_world)
87
+
kf_window.modal->update();
88
+
if (kf_window.menu && kf_window.menu->render_world)
89
+
kf_window.menu->update();
90
+
91
+
BeginDrawing();
92
+
ClearBackground(BLACK);
93
+
{
94
+
BeginMode2D(kf_window.cam);
95
+
{
96
+
if (kf_window.modal && kf_window.modal->render_world)
97
+
kf_window.modal->render_world();
98
+
if (kf_window.menu && kf_window.menu->render_world)
99
+
kf_window.menu->render_world();
100
+
}
101
+
EndMode2D();
102
+
103
+
if (kf_window.modal && kf_window.modal->render_ui)
104
+
kf_window.modal->render_ui();
105
+
if (kf_window.menu && kf_window.menu->render_ui)
106
+
kf_window.menu->render_ui();
107
+
}
108
+
EndDrawing();
109
+
110
+
kf_frame++;
111
+
kf_dts = GetFrameTime();
112
+
kf_dtms = kf_dts * 1000;
113
+
kf_s += kf_dts;
114
+
}
115
+
116
+
kf_setmenu(NULL);
117
+
kf_setmodal(NULL);
118
+
119
+
kf_window.state->player.pos = kf_window.player->pos;
120
+
kf_state_save(kf_window.state);
121
+
122
+
free(kf_window.player);
123
+
free(kf_window.state);
124
+
free(kf_window.room);
125
+
126
+
CloseWindow();
127
+
}
128
+
129
+
void kf_closewindow(void)
130
+
{
131
+
kf_window.running = false;
132
+
}
133
+
134
+
void kf_settargetfps(int fps)
135
+
{
136
+
SetTargetFPS(kf_window.target_fps = fps);
137
+
}
138
+
139
+
void kf_setmodal(struct kf_modal *modal)
140
+
{
141
+
if (kf_window.modal && kf_window.modal->exit)
142
+
{
143
+
kf_window.modal->exit();
144
+
kf_window.modal->exit = NULL;
145
+
}
146
+
kf_window.modal = modal;
147
+
if (kf_window.modal && kf_window.modal->init)
148
+
kf_window.modal->init();
149
+
}
150
+
151
+
void kf_setmenu(struct kf_modal *menu)
152
+
{
153
+
if (kf_window.menu && kf_window.menu->exit)
154
+
{
155
+
kf_window.menu->exit();
156
+
kf_window.menu->exit = NULL;
157
+
}
158
+
kf_window.menu = menu;
159
+
if (kf_window.menu && kf_window.menu->init)
160
+
kf_window.menu->init();
161
+
}
162
+
163
+
static
164
+
void _kf_modal_play_update(void)
165
+
{
166
+
kf_window.player->tick(kf_window.player);
167
+
168
+
Vector2 v = GetScreenToWorld2D(GetMousePosition(), kf_window.cam);
169
+
kf_window.select.x = v.x / KF_TILE_SIZE_PX;
170
+
kf_window.select.y = v.y / KF_TILE_SIZE_PX;
171
+
172
+
if (kf_checkinputpress(kf_inputbind_cancel) && kf_window.menu == NULL)
173
+
kf_window.running = 0;
174
+
else if (kf_checkinputpress(kf_inputbind_zoom_reset))
175
+
kf_window.cam.zoom = 2;
176
+
else if (kf_checkinputpress(kf_inputbind_zoom_in) && kf_window.cam.zoom < 3.50f)
177
+
kf_window.cam.zoom += 0.25f;
178
+
else if (kf_checkinputpress(kf_inputbind_zoom_out) && kf_window.cam.zoom > 1.00f)
179
+
kf_window.cam.zoom -= 0.25f;
180
+
else if (kf_checkinputpress(kf_inputbind_toggle_fps_limit))
181
+
kf_settargetfps(kf_window.target_fps != 60 ? 60 : 0);
182
+
else if (kf_checkinputpress(kf_inputbind_toggle_editor))
183
+
{
184
+
if (kf_window.modal == &kf_modal_edit)
185
+
kf_setmodal(&kf_modal_play);
186
+
else
187
+
kf_setmodal(&kf_modal_edit);
188
+
}
189
+
}
190
+
191
+
static
192
+
void _kf_modal_play_render_world(void)
193
+
{
194
+
kf_world_draw(kf_window.room, kf_window.cam);
195
+
// kf_world_drawcolliders(world, player, cam);
196
+
kf_window.player->draw(kf_window.player);
197
+
}
198
+
199
+
static
200
+
void _kf_modal_play_render_ui(void)
201
+
{
202
+
const int dy = kf_window.fontsize + 4;
203
+
int y = -dy + 4; /* start at -dy so that the FPS starts at 0,0. */
204
+
y += 8; /* add a bit of padding */
205
+
int x = 8;
206
+
207
+
const Color d = GRAY; /* default colour */
208
+
Color c = d;
209
+
210
+
/* "curry" some arguments */
211
+
# define line(FMT, ...) \
212
+
do \
213
+
{ \
214
+
char *t = (char *)TextFormat(FMT __VA_OPT__(,) __VA_ARGS__); \
215
+
kf_drawtextshadowed(c, x, y+=dy, kf_window.fontsize, t); \
216
+
} \
217
+
while (0)
218
+
219
+
line("--time--");
220
+
c = GetFPS() >= kf_window.target_fps ? GREEN : RED;
221
+
line("fps: %d", GetFPS());
222
+
line("dts: %f", kf_dts);
223
+
c = d;
224
+
line("sec: %f", kf_s);
225
+
226
+
line("--modals--");
227
+
c = kf_window.modal ? ORANGE : d;
228
+
line("mode: %s", kf_window.modal ? kf_window.modal->name : "n/a");
229
+
c = kf_window.menu ? ORANGE : d;
230
+
line("menu: %s", kf_window.menu ? kf_window.menu->name : "n/a");
231
+
232
+
# undef line
233
+
}
234
+
235
+
struct kf_modal kf_modal_play = {
236
+
.name = "play",
237
+
.update = _kf_modal_play_update,
238
+
.render_world = _kf_modal_play_render_world,
239
+
.render_ui = _kf_modal_play_render_ui,
240
+
};
-1
src/input.c
-1
src/input.c
+55
src/inputbinds.c
+55
src/inputbinds.c
···
1
+
#include <keraforge.h>
2
+
3
+
4
+
kf_inputbind_t
5
+
kf_inputbind_move_up,
6
+
kf_inputbind_move_down,
7
+
kf_inputbind_move_left,
8
+
kf_inputbind_move_right,
9
+
kf_inputbind_run,
10
+
11
+
kf_inputbind_ui_up,
12
+
kf_inputbind_ui_down,
13
+
kf_inputbind_ui_left,
14
+
kf_inputbind_ui_right,
15
+
kf_inputbind_select,
16
+
kf_inputbind_cancel,
17
+
18
+
kf_inputbind_pause,
19
+
kf_inputbind_palette,
20
+
21
+
kf_inputbind_zoom_reset,
22
+
kf_inputbind_zoom_in,
23
+
kf_inputbind_zoom_out,
24
+
25
+
kf_inputbind_toggle_fps_limit,
26
+
kf_inputbind_toggle_editor
27
+
;
28
+
29
+
30
+
void kf_loaddefaultbinds(void)
31
+
{
32
+
kf_inputbind_move_up = kf_addinput("move_up", KEY_W, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_Y);
33
+
kf_inputbind_move_down = kf_addinput("move_down", KEY_S, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_Y);
34
+
kf_inputbind_move_left = kf_addinput("move_left", KEY_A, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_X);
35
+
kf_inputbind_move_right = kf_addinput("move_right", KEY_D, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_X);
36
+
kf_inputbind_run = kf_addinput("run", KEY_LEFT_SHIFT, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
37
+
38
+
kf_inputbind_ui_up = kf_addinput("ui_up", KEY_W, KEY_UP, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_UP, GAMEPAD_AXIS_UNKNOWN);
39
+
kf_inputbind_ui_down = kf_addinput("ui_down", KEY_S, KEY_DOWN, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_DOWN, GAMEPAD_AXIS_UNKNOWN);
40
+
kf_inputbind_ui_left = kf_addinput("ui_left", KEY_A, KEY_LEFT, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_LEFT, GAMEPAD_AXIS_UNKNOWN);
41
+
kf_inputbind_ui_right = kf_addinput("ui_right", KEY_D, KEY_RIGHT, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
42
+
43
+
kf_inputbind_select = kf_addinput("select", KEY_E, KEY_ENTER, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_DOWN, GAMEPAD_AXIS_UNKNOWN);
44
+
kf_inputbind_cancel = kf_addinput("cancel", KEY_Q, KEY_ESCAPE, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
45
+
46
+
kf_inputbind_pause = kf_addinput("pause", KEY_ESCAPE, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_MIDDLE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
47
+
kf_inputbind_palette = kf_addinput("palette", KEY_TAB, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_UP, GAMEPAD_AXIS_UNKNOWN);
48
+
49
+
kf_inputbind_zoom_reset = kf_addinput("zoom_reset", KEY_ZERO, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
50
+
kf_inputbind_zoom_in = kf_addinput("zoom_in", KEY_EQUAL, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
51
+
kf_inputbind_zoom_out = kf_addinput("zoom_out", KEY_MINUS, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
52
+
53
+
kf_inputbind_toggle_fps_limit = kf_addinput("toggle_fps_limit", KEY_NINE, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
54
+
kf_inputbind_toggle_editor = kf_addinput("toggle_editor", KEY_EIGHT, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
55
+
}
+4
-330
src/main.c
+4
-330
src/main.c
···
1
-
#include "keraforge/world.h"
2
1
#include <keraforge.h>
3
2
#include <raylib.h>
4
3
#include <raymath.h>
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 enum {
13
-
menu_none,
14
-
menu_palette,
15
-
} menu;
16
-
static int target_fps = 60;
17
-
static enum {
18
-
modal_play,
19
-
modal_edit,
20
-
} modal;
21
-
static char *modals[] = { "play", "edit" };
22
-
static bool dirty = false;
23
-
24
-
static kf_inputbind_t
25
-
inputbind_move_up,
26
-
inputbind_move_down,
27
-
inputbind_move_left,
28
-
inputbind_move_right,
29
-
inputbind_run,
30
-
inputbind_ui_up,
31
-
inputbind_ui_down,
32
-
inputbind_ui_left,
33
-
inputbind_ui_right,
34
-
inputbind_select,
35
-
inputbind_cancel,
36
-
inputbind_pause,
37
-
inputbind_palette,
38
-
inputbind_zoom_reset,
39
-
inputbind_zoom_in,
40
-
inputbind_zoom_out,
41
-
inputbind_toggle_fps_limit,
42
-
inputbind_toggle_editor
43
-
;
44
4
45
5
46
6
static
47
-
void loadbinds(void)
48
-
{
49
-
inputbind_move_up = kf_addinput("move_up", KEY_W, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_Y);
50
-
inputbind_move_down = kf_addinput("move_down", KEY_S, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_Y);
51
-
inputbind_move_left = kf_addinput("move_left", KEY_A, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_X);
52
-
inputbind_move_right = kf_addinput("move_right", KEY_D, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_LEFT_X);
53
-
inputbind_run = kf_addinput("run", KEY_LEFT_SHIFT, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
54
-
55
-
inputbind_ui_up = kf_addinput("ui_up", KEY_W, KEY_UP, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_UP, GAMEPAD_AXIS_UNKNOWN);
56
-
inputbind_ui_down = kf_addinput("ui_down", KEY_S, KEY_DOWN, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_DOWN, GAMEPAD_AXIS_UNKNOWN);
57
-
inputbind_ui_left = kf_addinput("ui_left", KEY_A, KEY_LEFT, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_LEFT, GAMEPAD_AXIS_UNKNOWN);
58
-
inputbind_ui_right = kf_addinput("ui_right", KEY_D, KEY_RIGHT, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_LEFT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
59
-
60
-
inputbind_select = kf_addinput("select", KEY_E, KEY_ENTER, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_DOWN, GAMEPAD_AXIS_UNKNOWN);
61
-
inputbind_cancel = kf_addinput("cancel", KEY_Q, KEY_ESCAPE, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
62
-
63
-
inputbind_pause = kf_addinput("pause", KEY_ESCAPE, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_MIDDLE_RIGHT, GAMEPAD_AXIS_UNKNOWN);
64
-
inputbind_palette = kf_addinput("palette", KEY_TAB, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_RIGHT_FACE_UP, GAMEPAD_AXIS_UNKNOWN);
65
-
66
-
inputbind_zoom_reset = kf_addinput("zoom_reset", KEY_ZERO, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
67
-
inputbind_zoom_in = kf_addinput("zoom_in", KEY_EQUAL, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
68
-
inputbind_zoom_out = kf_addinput("zoom_out", KEY_MINUS, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
69
-
70
-
inputbind_toggle_fps_limit = kf_addinput("toggle_fps_limit", KEY_NINE, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
71
-
inputbind_toggle_editor = kf_addinput("toggle_editor", KEY_EIGHT, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN);
72
-
}
73
-
74
-
static
75
7
void loadtiles(struct kf_spritesheet *terrain)
76
8
{
77
9
KF_ADDTILE(
···
128
60
kf_logdbg("loaded %d tiles", kf_tiles.count);
129
61
}
130
62
131
-
static
132
-
void setmenu(int m)
133
-
{
134
-
menu = m;
135
-
}
136
-
137
-
static
138
-
void _player_tick_move(struct kf_actor *self)
139
-
{
140
-
struct kf_vec2(f32) v = {0, 0};
141
-
142
-
/* gamepad axis movement */
143
-
f32 gpx = kf_getgamepadaxis(inputbind_move_left);
144
-
f32 gpy = kf_getgamepadaxis(inputbind_move_up);
145
-
if (gpx > kf_deadzone || gpx < -kf_deadzone || gpy > kf_deadzone || gpy < -kf_deadzone)
146
-
{
147
-
v.y = gpy;
148
-
v.x = gpx;
149
-
150
-
f32 angle = Vector2LineAngle(Vector2Zero(), (Vector2){gpx, gpy}) * RAD2DEG;
151
-
angle /= 90;
152
-
switch ((int)roundf(angle))
153
-
{
154
-
case 0: self->pointing = kf_east; break;
155
-
case 1: self->pointing = kf_north; break;
156
-
case -2: /* fallthrough */
157
-
case 2: self->pointing = kf_west; break;
158
-
case -1: self->pointing = kf_south; break;
159
-
}
160
-
161
-
goto done;
162
-
}
163
-
164
-
/* non-axis movement */
165
-
bool w = kf_checkinputdown(inputbind_move_up);
166
-
bool s = kf_checkinputdown(inputbind_move_down);
167
-
bool a = kf_checkinputdown(inputbind_move_left);
168
-
bool d = kf_checkinputdown(inputbind_move_right);
169
-
170
-
if (a && d) { v.x = 0; }
171
-
else if (a) { v.x = -1; self->pointing = kf_west; }
172
-
else if (d) { v.x = 1; self->pointing = kf_east; }
173
-
174
-
if (w && s) { v.y = 0; }
175
-
else if (w) { v.y = -1; self->pointing = kf_north; }
176
-
else if (s) { v.y = 1; self->pointing = kf_south; }
177
-
178
-
v = kf_normalize_vec2(f32)(v);
179
-
180
-
done:
181
-
if (v.x || v.y)
182
-
kf_actor_addforce(self, v);
183
-
}
184
-
185
-
static
186
-
void _player_tick(struct kf_world *world, struct kf_actor *self)
187
-
{
188
-
if (menu == menu_none)
189
-
{
190
-
_player_tick_move(self);
191
-
192
-
if (kf_checkinputpress(inputbind_run))
193
-
{
194
-
self->running = true;
195
-
self->speedmod = 1.5;
196
-
}
197
-
else if (kf_checkinputrelease(inputbind_run))
198
-
{
199
-
self->running = false;
200
-
self->speedmod = 1;
201
-
}
202
-
}
203
-
204
-
kf_actor_move(world, self, kf_dts);
205
-
}
206
-
207
-
static
208
-
void _player_draw(struct kf_world *world, struct kf_actor *self)
209
-
{
210
-
(void)world;
211
-
kf_actor_draw(self);
212
-
213
-
cam.target.x = self->pos.x + (self->size.x / 2);
214
-
cam.target.y = self->pos.y + (self->size.y / 2);
215
-
}
216
-
217
-
static
218
-
void draw_palette(int *selected)
219
-
{
220
-
int px = 80, py = 80;
221
-
DrawRectangle(px, py, 400, 400, BLACK);
222
-
DrawText("tiles :3", px + 10, py + 10, 20, WHITE);
223
-
py += 40;
224
-
int x = 0, y = 0;
225
-
int s = KF_TILE_SIZE_PX * 2;
226
-
for (int i = 1 ; i <= kf_tiles.count ; i++)
227
-
{
228
-
Rectangle r = {px + x*s, py + y*s, s, s};
229
-
kf_drawsprite_wh(kf_tiles.sheet[i], r.x, r.y, r.width, r.height, kf_tiles.sprite[i].x + 0, kf_tiles.sprite[i].y + 3);
230
-
231
-
if (*selected == i)
232
-
DrawRectangleLinesEx(r, 1, GOLD);
233
-
234
-
if (CheckCollisionPointRec(GetMousePosition(), r))
235
-
{
236
-
DrawRectangleLinesEx(r, 1, WHITE);
237
-
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
238
-
*selected = i;
239
-
}
240
-
241
-
x += 1;
242
-
if (x >= 8)
243
-
{
244
-
x = 0;
245
-
y++;
246
-
}
247
-
}
248
-
249
-
if (kf_checkinputpress(inputbind_cancel))
250
-
setmenu(menu_none);
251
-
};
252
-
253
63
254
64
int main(int argc, const char *argv[])
255
65
{
256
66
(void)argc;
257
67
(void)argv;
258
68
259
-
SetTraceLogLevel(LOG_WARNING);
260
-
InitWindow(800, 600, "Keraforge");
261
-
SetTargetFPS(target_fps);
262
-
SetExitKey(KEY_NULL);
69
+
kf_openwindow("Keraforge");
263
70
264
-
loadbinds();
71
+
kf_window.font = LoadFont("data/res/font/MyDearestBit.ttf");
72
+
kf_window.fontsize = 16;
265
73
266
74
struct kf_spritesheet terrain = kf_loadspritesheet("data/res/img/tile/terrain.png", 16, 16);
267
75
loadtiles(&terrain);
268
76
269
-
struct kf_uiconfig *uiconfig = kf_ui_getconfig();
270
-
uiconfig->select = inputbind_select;
271
-
uiconfig->cancel = inputbind_cancel;
272
-
uiconfig->up = inputbind_ui_up;
273
-
uiconfig->down = inputbind_ui_down;
274
-
275
-
if (!DirectoryExists("data"))
276
-
MakeDirectory("data");
277
-
278
-
struct kf_state *state = NULL;
279
-
int is_new_state = kf_state_load(&state);
280
-
281
-
struct kf_world *world = NULL;
282
-
kf_world_load(&world, true);
283
-
if (!world)
284
-
KF_THROW("failed to load world");
285
-
286
-
struct kf_actor *player = kf_actor_new(kf_actor_loadspritesheet("data/res/img/char/template.png"), 10, 10, true);
287
-
player->sizeoffset.y = 6;
288
-
player->tick = _player_tick;
289
-
player->draw = _player_draw;
290
-
player->controlled = true;
291
-
if (is_new_state)
292
-
{
293
-
state->player.pos.x = world->width * KF_TILE_SIZE_PX / 2.0f;
294
-
state->player.pos.y = world->width * KF_TILE_SIZE_PX / 2.0f;
295
-
}
296
-
player->pos.x = state->player.pos.x;
297
-
player->pos.y = state->player.pos.y;
298
-
kf_loginfo("pos: %f,%f", player->pos.x, player->pos.y);
299
-
300
-
cam = (Camera2D){0};
301
-
cam.offset.x = GetScreenWidth() / 2.0f;
302
-
cam.offset.y = GetScreenHeight() / 2.0f;
303
-
cam.target.x = player->pos.x + (player->size.x / 2);
304
-
cam.target.y = player->pos.y + (player->size.y / 2);
305
-
cam.zoom = 2;
306
-
307
-
int running = 1;
308
-
while (!WindowShouldClose() && running)
309
-
{
310
-
if (IsWindowResized())
311
-
{
312
-
cam.offset.x = GetScreenWidth() / 2.0f;
313
-
cam.offset.y = GetScreenHeight() / 2.0f;
314
-
}
315
-
316
-
player->tick(world, player);
317
-
318
-
Vector2 v = GetScreenToWorld2D(GetMousePosition(), cam);
319
-
select.x = v.x / KF_TILE_SIZE_PX;
320
-
select.y = v.y / KF_TILE_SIZE_PX;
321
-
322
-
if (kf_checkinputpress(inputbind_palette) && modal == modal_edit)
323
-
setmenu(menu_palette);
324
-
else if (kf_checkinputpress(inputbind_cancel) && menu == menu_none)
325
-
running = 0;
326
-
else if (kf_checkinputpress(inputbind_zoom_reset))
327
-
cam.zoom = 2;
328
-
else if (kf_checkinputpress(inputbind_zoom_in) && cam.zoom < 3.50f)
329
-
cam.zoom += 0.25f;
330
-
else if (kf_checkinputpress(inputbind_zoom_out) && cam.zoom > 1.00f)
331
-
cam.zoom -= 0.25f;
332
-
else if (kf_checkinputpress(inputbind_toggle_fps_limit))
333
-
{
334
-
target_fps = target_fps <= 0 ? 60 : 0;
335
-
SetTargetFPS(target_fps);
336
-
}
337
-
else if (kf_checkinputpress(inputbind_toggle_editor))
338
-
{
339
-
if (modal == modal_edit)
340
-
modal = modal_play;
341
-
else
342
-
{
343
-
modal = modal_edit;
344
-
dirty = true;
345
-
}
346
-
}
347
-
348
-
BeginDrawing();
349
-
ClearBackground(BLACK);
350
-
351
-
BeginMode2D(cam);
352
-
kf_world_draw(world, cam);
353
-
// kf_world_drawcolliders(world, player, cam);
354
-
if (modal == modal_edit && menu == menu_none && select.x < world->width && select.y < world->height)
355
-
{
356
-
struct kf_tile *t = kf_world_gettile(world, select.x, select.y);
357
-
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
358
-
{
359
-
t->id = (kf_tileid_t)selected_tile;
360
-
kf_world_updatetile(world, select.x, select.y, true);
361
-
}
362
-
else if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
363
-
t->subid = (kf_tileid_t)selected_tile;
364
-
else if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE))
365
-
selected_tile = t->id;
366
-
367
-
DrawRectangleLines(select.x * KF_TILE_SIZE_PX, select.y * KF_TILE_SIZE_PX, KF_TILE_SIZE_PX, KF_TILE_SIZE_PX, WHITE);
368
-
DrawText(TextFormat("%d [%d] (%d,%d)", t->id, t->data, select.x, select.y), select.x * KF_TILE_SIZE_PX, select.y * KF_TILE_SIZE_PX - 10, 10, BLACK);
369
-
}
370
-
player->draw(world, player);
371
-
EndMode2D();
372
-
373
-
switch (menu)
374
-
{
375
-
case menu_none:
376
-
break;
377
-
case menu_palette:
378
-
draw_palette(&selected_tile);
379
-
break;
380
-
}
381
-
382
-
DrawFPS(0, 0);
383
-
DrawText(TextFormat("%f", kf_dts), 0, 20, 20, RED);
384
-
DrawText(TextFormat("%f", kf_s), 0, 40, 20, RED);
385
-
DrawText(TextFormat("%s", modals[modal]), 0, 60, 20, ORANGE);
386
-
387
-
EndDrawing();
388
-
389
-
kf_frame++;
390
-
kf_dts = GetFrameTime();
391
-
kf_dtms = kf_dts * 1000;
392
-
kf_s += kf_dts;
393
-
}
394
-
395
-
state->player.pos = player->pos;
396
-
kf_state_save(state);
397
-
free(state);
398
-
399
-
if (dirty)
400
-
kf_world_save(world, true);
401
-
free(world);
402
-
403
-
CloseWindow();
77
+
kf_startwindow();
404
78
405
79
return 0;
406
80
}
+79
src/player.c
+79
src/player.c
···
1
+
#include <keraforge.h>
2
+
3
+
4
+
static
5
+
void _player_tick_move(struct kf_actor *self)
6
+
{
7
+
struct kf_vec2(f32) v = {0, 0};
8
+
9
+
/* gamepad axis movement */
10
+
f32 gpx = kf_getgamepadaxis(kf_inputbind_move_left);
11
+
f32 gpy = kf_getgamepadaxis(kf_inputbind_move_up);
12
+
if (gpx > kf_deadzone || gpx < -kf_deadzone || gpy > kf_deadzone || gpy < -kf_deadzone)
13
+
{
14
+
v.y = gpy;
15
+
v.x = gpx;
16
+
17
+
f32 angle = Vector2LineAngle(Vector2Zero(), (Vector2){gpx, gpy}) * RAD2DEG;
18
+
angle /= 90;
19
+
switch ((int)roundf(angle))
20
+
{
21
+
case 0: self->pointing = kf_east; break;
22
+
case 1: self->pointing = kf_north; break;
23
+
case -2: /* fallthrough */
24
+
case 2: self->pointing = kf_west; break;
25
+
case -1: self->pointing = kf_south; break;
26
+
}
27
+
28
+
goto done;
29
+
}
30
+
31
+
/* non-axis movement */
32
+
bool w = kf_checkinputdown(kf_inputbind_move_up);
33
+
bool s = kf_checkinputdown(kf_inputbind_move_down);
34
+
bool a = kf_checkinputdown(kf_inputbind_move_left);
35
+
bool d = kf_checkinputdown(kf_inputbind_move_right);
36
+
37
+
if (a && d) { v.x = 0; }
38
+
else if (a) { v.x = -1; self->pointing = kf_west; }
39
+
else if (d) { v.x = 1; self->pointing = kf_east; }
40
+
41
+
if (w && s) { v.y = 0; }
42
+
else if (w) { v.y = -1; self->pointing = kf_north; }
43
+
else if (s) { v.y = 1; self->pointing = kf_south; }
44
+
45
+
v = kf_normalize_vec2(f32)(v);
46
+
47
+
done:
48
+
if (v.x || v.y)
49
+
kf_actor_addforce(self, v);
50
+
}
51
+
52
+
void kf_player_tick(struct kf_actor *self)
53
+
{
54
+
if (!kf_window.menu)
55
+
{
56
+
_player_tick_move(self);
57
+
58
+
if (kf_checkinputpress(kf_inputbind_run))
59
+
{
60
+
self->running = true;
61
+
self->speedmod = 1.5;
62
+
}
63
+
else if (kf_checkinputrelease(kf_inputbind_run))
64
+
{
65
+
self->running = false;
66
+
self->speedmod = 1;
67
+
}
68
+
}
69
+
70
+
kf_actor_move(kf_window.room, self, kf_dts);
71
+
}
72
+
73
+
void kf_player_draw(struct kf_actor *self)
74
+
{
75
+
kf_actor_draw(self);
76
+
77
+
kf_window.cam.target.x = self->pos.x + (self->size.x / 2);
78
+
kf_window.cam.target.y = self->pos.y + (self->size.y / 2);
79
+
}
+22
-18
src/ui.c
+22
-18
src/ui.c
···
1
+
#include "keraforge/graphics.h"
1
2
#include <keraforge.h>
2
3
#include <raylib.h>
3
4
4
5
5
-
static
6
-
struct kf_uiconfig _kf_uiconfig = {
6
+
struct kf_uiconfig kf_uiconfig = {
7
7
.select = KF_INPUTBIND_NONE,
8
8
.cancel = KF_INPUTBIND_NONE,
9
9
.up = KF_INPUTBIND_NONE,
···
19
19
};
20
20
21
21
22
-
struct kf_uiconfig *kf_ui_getconfig(void)
22
+
void kf_ui_init(void)
23
23
{
24
-
return &_kf_uiconfig;
24
+
kf_uiconfig.select = kf_inputbind_select;
25
+
kf_uiconfig.cancel = kf_inputbind_cancel;
26
+
kf_uiconfig.up = kf_inputbind_ui_up;
27
+
kf_uiconfig.down = kf_inputbind_ui_down;
28
+
kf_uiconfig.fontsize = kf_window.fontsize;
25
29
}
26
30
27
31
int kf_ui_panel(char *title)
28
32
{
29
-
int y = GetScreenHeight() - _kf_uiconfig.panelheight;
30
-
DrawRectangle(0, y, GetScreenWidth(), _kf_uiconfig.panelheight, _kf_uiconfig.bg);
33
+
int y = GetScreenHeight() - kf_uiconfig.panelheight;
34
+
DrawRectangle(0, y, GetScreenWidth(), kf_uiconfig.panelheight, kf_uiconfig.bg);
31
35
32
36
if (title)
33
37
{
34
-
y += _kf_uiconfig.ypadding;
35
-
DrawText(title, _kf_uiconfig.xpadding, y, _kf_uiconfig.fontsize, _kf_uiconfig.fg);
36
-
y += _kf_uiconfig.fontsize;
38
+
y += kf_uiconfig.ypadding;
39
+
kf_drawtextshadowed(kf_uiconfig.fg, kf_uiconfig.xpadding, y, kf_uiconfig.fontsize, title);
40
+
y += kf_uiconfig.fontsize;
37
41
}
38
42
39
43
return y;
···
50
54
{
51
55
char *c = choices[i];
52
56
53
-
DrawText(
54
-
TextFormat(i == *choice ? _kf_uiconfig.selectfmt : _kf_uiconfig.fmt, c),
55
-
_kf_uiconfig.xpadding,
57
+
kf_drawtextshadowed(
58
+
kf_uiconfig.fg,
59
+
kf_uiconfig.xpadding,
56
60
y,
57
-
_kf_uiconfig.fontsize,
58
-
_kf_uiconfig.fg
61
+
kf_uiconfig.fontsize,
62
+
(char *)TextFormat(i == *choice ? kf_uiconfig.selectfmt : kf_uiconfig.fmt, c)
59
63
);
60
64
61
-
y += _kf_uiconfig.fontsize;
65
+
y += kf_uiconfig.fontsize;
62
66
if (y >= GetScreenHeight())
63
67
break;
64
68
}
65
69
66
70
skip_text:
67
71
68
-
if (kf_checkinputpress(_kf_uiconfig.select) || kf_checkinputpress(_kf_uiconfig.cancel))
72
+
if (kf_checkinputpress(kf_uiconfig.select) || kf_checkinputpress(kf_uiconfig.cancel))
69
73
return 1;
70
-
else if (kf_checkinputpress(_kf_uiconfig.down) && *choice < nchoices - 1)
74
+
else if (kf_checkinputpress(kf_uiconfig.down) && *choice < nchoices - 1)
71
75
(*choice)++;
72
-
else if (kf_checkinputpress(_kf_uiconfig.up) && *choice > 0)
76
+
else if (kf_checkinputpress(kf_uiconfig.up) && *choice > 0)
73
77
(*choice)--;
74
78
75
79
return 0;