A game engine for top-down 2D RPG games.
rpg game-engine raylib c99

Improve tile palette

Changed files
+76 -9
src
+75 -8
src/main.c
··· 1 1 #include "keraforge/input.h" 2 + #include "keraforge/sprites.h" 3 + #include "keraforge/world.h" 2 4 #include <keraforge.h> 3 5 #include <raylib.h> 4 6 #include <raymath.h> ··· 14 16 menu_palette, 15 17 } menu; 16 18 static int target_fps = 60; 19 + static enum { 20 + modal_play, 21 + modal_edit, 22 + } modal; 23 + static char *modals[] = { "play", "edit" }; 24 + static bool dirty = false; 17 25 18 26 static kf_inputbind_t 19 27 inputbind_move_up, ··· 31 39 inputbind_zoom_reset, 32 40 inputbind_zoom_in, 33 41 inputbind_zoom_out, 34 - inputbind_toggle_fps_limit 42 + inputbind_toggle_fps_limit, 43 + inputbind_toggle_editor 35 44 ; 36 45 37 46 ··· 59 68 inputbind_zoom_out = kf_addinput("zoom_out", KEY_MINUS, KEY_NULL, MOUSE_BUTTON_UNKNOWN, GAMEPAD_BUTTON_UNKNOWN, GAMEPAD_AXIS_UNKNOWN); 60 69 61 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); 62 72 } 63 73 64 74 static ··· 134 144 cam.target.y = self->pos.y + (self->size.y / 2); 135 145 } 136 146 147 + static 148 + void draw_palette(int *selected) 149 + { 150 + int px = 80, py = 80; 151 + DrawRectangle(px, py, 400, 400, BLACK); 152 + DrawText("tiles :3", px + 10, py + 10, 20, WHITE); 153 + py += 40; 154 + int x = 0, y = 0; 155 + int s = KF_TILE_SIZE_PX * 2; 156 + for (int i = 1 ; i <= kf_tiles.count ; i++) 157 + { 158 + Rectangle r = {px + x*s, py + y*s, s, s}; 159 + 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); 160 + 161 + if (*selected == i) 162 + DrawRectangleLinesEx(r, 1, GOLD); 163 + 164 + if (CheckCollisionPointRec(GetMousePosition(), r)) 165 + { 166 + DrawRectangleLinesEx(r, 1, WHITE); 167 + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) 168 + *selected = i; 169 + } 170 + 171 + x += 1; 172 + if (x >= 8) 173 + { 174 + x = 0; 175 + y++; 176 + } 177 + } 178 + 179 + if (kf_checkinputpress(inputbind_cancel)) 180 + setmenu(menu_none); 181 + }; 182 + 137 183 138 184 int main(int argc, const char *argv[]) 139 185 { ··· 165 211 .mapcol = GRAY, 166 212 .sheet = &terrain, 167 213 .sprite = {0, 4}, 168 - .collide = true, 169 214 ); 170 215 KF_ADDTILE( 171 216 .key = "debug", ··· 173 218 .sheet = &terrain, 174 219 .sprite = {4, 4}, 175 220 ); 221 + KF_ADDTILE( 222 + .key = "brick", 223 + .mapcol = RED, 224 + .sheet = &terrain, 225 + .sprite = {8, 0}, 226 + .collide = true, 227 + ); 176 228 printf("loaded %d tiles\n", kf_tiles.count); 177 229 178 230 struct kf_uiconfig *uiconfig = kf_ui_getconfig(); ··· 240 292 select.x = v.x / KF_TILE_SIZE_PX; 241 293 select.y = v.y / KF_TILE_SIZE_PX; 242 294 243 - if (kf_checkinputpress(inputbind_palette)) 295 + if (kf_checkinputpress(inputbind_palette) && modal == modal_edit) 244 296 setmenu(menu_palette); 245 297 else if (kf_checkinputpress(inputbind_cancel) && menu == menu_none) 246 298 running = 0; ··· 255 307 target_fps = target_fps <= 0 ? 60 : 0; 256 308 SetTargetFPS(target_fps); 257 309 } 310 + else if (kf_checkinputpress(inputbind_toggle_editor)) 311 + { 312 + if (modal == modal_edit) 313 + modal = modal_play; 314 + else 315 + { 316 + modal = modal_edit; 317 + dirty = true; 318 + } 319 + } 258 320 259 321 BeginDrawing(); 260 322 ClearBackground(BLACK); ··· 262 324 BeginMode2D(cam); 263 325 kf_world_draw(world, cam); 264 326 // kf_world_drawcolliders(world, player, cam); 265 - if (select.x < world->width && select.y < world->height) 327 + if (modal == modal_edit && menu == menu_none && select.x < world->width && select.y < world->height) 266 328 { 267 329 struct kf_tile *t = kf_world_gettile(world, select.x, select.y); 268 - if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) 330 + if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) 269 331 { 270 332 t->id = (kf_tileid_t)selected_tile; 271 333 kf_world_updatetile(world, select.x, select.y, true); 272 334 } 335 + else if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) 336 + t->subid = (kf_tileid_t)selected_tile; 337 + else if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE)) 338 + selected_tile = t->id; 339 + 273 340 DrawRectangleLines(select.x * KF_TILE_SIZE_PX, select.y * KF_TILE_SIZE_PX, KF_TILE_SIZE_PX, KF_TILE_SIZE_PX, WHITE); 274 341 struct kf_vec2(u32) s = kf_getspritefortilebitmask(t->data); 275 342 DrawText(TextFormat("%d [0x%04x] (%d,%d) {%d,%d}", t->id, t->data, select.x, select.y, s.x, s.y), select.x * KF_TILE_SIZE_PX, select.y * KF_TILE_SIZE_PX - 10, 10, BLACK); ··· 282 349 case menu_none: 283 350 break; 284 351 case menu_palette: 285 - if (kf_ui_choice("Select tile", &kf_tiles.key[0], kf_tiles.count + 1, &selected_tile)) 286 - setmenu(menu_none); 352 + draw_palette(&selected_tile); 287 353 break; 288 354 } 289 355 290 356 DrawFPS(0, 0); 291 357 DrawText(TextFormat("%f", kf_dts), 0, 20, 20, RED); 292 358 DrawText(TextFormat("%f", kf_s), 0, 40, 20, RED); 359 + DrawText(TextFormat("%s", modals[modal]), 0, 60, 20, ORANGE); 293 360 294 361 EndDrawing(); 295 362 ··· 301 368 302 369 if (world) 303 370 { 304 - if (!kf_writebin("data/map.bin", (u8 *)world, kf_world_getsize(world))) 371 + if (dirty && !kf_writebin("data/map.bin", (u8 *)world, kf_world_getsize(world))) 305 372 fprintf(stderr, "error: failed to save map.bin\n"); 306 373 free(world); 307 374 }
+1 -1
src/world.c
··· 183 183 { 184 184 KF_SANITY_CHECK(tile->subid <= kf_tiles.count, "erroneous subtile on map at %u,%u: %u (count=%u)", x, y, tile->subid, kf_tiles.count); 185 185 KF_SANITY_CHECK(tile->id <= kf_tiles.count, "erroneous tile on map at %u,%u: %u (count=%u)", x, y, tile->id, kf_tiles.count); 186 - if (tile->data != 0x1111 && tile->subid) /* 0x1111: full tile, no subtile rendering needed */ 186 + if (tile->data != 0x1111 && tile->subid && tile->id) /* 0x1111: full tile, no subtile rendering needed */ 187 187 { 188 188 kf_drawsprite_wh( 189 189 kf_tiles.sheet[tile->subid],