A game engine for top-down 2D RPG games.
rpg
game-engine
raylib
c99
1#include "keraforge/editor.h"
2#include "keraforge/graphics.h"
3#include "keraforge/world.h"
4#include <keraforge.h>
5
6
7static
8void _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
16static
17void _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_timeit("save world", kf_world_save(kf_window.room, true, NULL));
25
26 free(kf_window.modal->data);
27 kf_window.modal->data = NULL;
28}
29
30static
31void _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
40static
41void _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
84static
85void _kf_modal_edit_render_ui()
86{
87 /* Inherit from kf_modal_play. */
88 kf_modal_play.render_ui();
89}
90
91struct 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
102static
103void _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
140struct kf_modal kf_menu_palette = {
141 .name = "tile palette",
142 .render_ui = _kf_menu_palette_render_ui,
143};