Add in-game level editor with auto-discovered tile/entity palettes
Implements a full level editor that runs inside the game engine as an alternative mode, accessible via --edit flag or E key during gameplay. The editor auto-discovers available tiles from the tileset texture and entities from a new central registry, so adding new game content automatically appears in the editor without any editor-specific changes. Editor features: tile painting (pencil/eraser/flood fill) across 3 layers, entity placement with drag-to-move, player spawn point tool, camera pan/zoom, grid overlay, .lvl save/load, map resize, and test play (P to play, ESC to return to editor). Supporting changes: - Entity registry centralizes spawn functions (replaces strcmp chain) - Mouse input + raw keyboard access added to input system - Camera zoom support for editor overview - Zoom-aware rendering in tilemap, renderer, and sprite systems - Powerup and drone sprites/animations wired up (were defined but unused) - Bitmap font renderer for editor UI (4x6 pixel glyphs, no dependencies)
This commit is contained in:
98
src/game/editor.h
Normal file
98
src/game/editor.h
Normal file
@@ -0,0 +1,98 @@
|
||||
#ifndef JNR_EDITOR_H
|
||||
#define JNR_EDITOR_H
|
||||
|
||||
#include "engine/tilemap.h"
|
||||
#include "engine/camera.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* ═══════════════════════════════════════════════════
|
||||
* Level Editor
|
||||
*
|
||||
* An in-engine level editor that runs as an
|
||||
* alternative game mode. Uses the same renderer,
|
||||
* camera, and tilemap systems as gameplay.
|
||||
*
|
||||
* Tile palette is auto-discovered from the tileset
|
||||
* texture. Entity palette is auto-discovered from
|
||||
* the entity registry. Adding new tiles or entities
|
||||
* to the game makes them appear in the editor
|
||||
* automatically.
|
||||
* ═══════════════════════════════════════════════════ */
|
||||
|
||||
typedef enum EditorTool {
|
||||
TOOL_PENCIL, /* paint tiles */
|
||||
TOOL_ERASER, /* clear tiles (paint tile 0) */
|
||||
TOOL_FILL, /* flood fill area */
|
||||
TOOL_ENTITY, /* place/select entities */
|
||||
TOOL_SPAWN, /* set player spawn point */
|
||||
TOOL_COUNT
|
||||
} EditorTool;
|
||||
|
||||
typedef enum EditorLayer {
|
||||
EDITOR_LAYER_COLLISION,
|
||||
EDITOR_LAYER_BG,
|
||||
EDITOR_LAYER_FG,
|
||||
EDITOR_LAYER_COUNT
|
||||
} EditorLayer;
|
||||
|
||||
/* UI panel regions */
|
||||
#define EDITOR_TOOLBAR_H 14 /* top bar height */
|
||||
#define EDITOR_PALETTE_W 80 /* right panel width */
|
||||
#define EDITOR_STATUS_H 10 /* bottom status bar height */
|
||||
|
||||
typedef struct Editor {
|
||||
/* ── Map data ──────────────────────────── */
|
||||
Tilemap map;
|
||||
char file_path[256];
|
||||
bool has_file; /* true if loaded from / saved to file */
|
||||
bool dirty; /* unsaved changes */
|
||||
|
||||
/* ── Camera ────────────────────────────── */
|
||||
Camera camera;
|
||||
|
||||
/* ── Tool state ────────────────────────── */
|
||||
EditorTool tool;
|
||||
EditorLayer active_layer;
|
||||
uint16_t selected_tile; /* currently selected tile ID */
|
||||
int selected_entity; /* index into entity registry */
|
||||
bool show_grid;
|
||||
bool show_all_layers; /* dim inactive layers */
|
||||
|
||||
/* ── Entity editing ────────────────────── */
|
||||
int dragging_entity; /* index in entity_spawns, or -1 */
|
||||
float drag_offset_x; /* offset from entity origin to mouse */
|
||||
float drag_offset_y;
|
||||
|
||||
/* ── Palette scroll ────────────────────── */
|
||||
int tile_palette_scroll;
|
||||
int entity_palette_scroll;
|
||||
|
||||
/* ── Tileset info (auto-discovered) ────── */
|
||||
int tileset_cols;
|
||||
int tileset_rows;
|
||||
int tileset_total; /* total tiles in tileset */
|
||||
|
||||
/* ── UI state ──────────────────────────── */
|
||||
bool active; /* editor is running */
|
||||
} Editor;
|
||||
|
||||
/* Lifecycle */
|
||||
void editor_init(Editor *ed);
|
||||
void editor_new_level(Editor *ed, int width, int height);
|
||||
bool editor_load(Editor *ed, const char *path);
|
||||
bool editor_save(Editor *ed);
|
||||
bool editor_save_as(Editor *ed, const char *path);
|
||||
void editor_free(Editor *ed);
|
||||
|
||||
/* Frame callbacks (plug into engine) */
|
||||
void editor_update(Editor *ed, float dt);
|
||||
void editor_render(Editor *ed, float interpolation);
|
||||
|
||||
/* Returns true if the user pressed the test-play key */
|
||||
bool editor_wants_test_play(Editor *ed);
|
||||
|
||||
/* Returns true if the editor wants to quit */
|
||||
bool editor_wants_quit(Editor *ed);
|
||||
|
||||
#endif /* JNR_EDITOR_H */
|
||||
Reference in New Issue
Block a user