Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_iso_engine.h
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
46#ifndef NILOREA_ISOMETRIC_ENGINE
47#define NILOREA_ISOMETRIC_ENGINE
48
49#ifdef __cplusplus
50extern "C" {
51#endif
52
58#include "n_common.h"
59#include "n_log.h"
60
61/* Ability flags */
62
64#define WALK 1
66#define SWIM 2
68#define BLCK 3
69
70/* Terrain transition bitmask definitions (Article 934)
71 * Edge bits represent which cardinal sides have a higher-priority terrain.
72 * Corner bits represent which diagonal neighbors have a higher-priority
73 * terrain (only when the adjacent edges do NOT have that terrain).
74 */
75
77#define ISO_EDGE_W (1 << 0)
79#define ISO_EDGE_N (1 << 1)
81#define ISO_EDGE_E (1 << 2)
83#define ISO_EDGE_S (1 << 3)
85#define ISO_NUM_EDGE_MASKS 16
86
88#define ISO_CORNER_NW (1 << 0)
90#define ISO_CORNER_NE (1 << 1)
92#define ISO_CORNER_SE (1 << 2)
94#define ISO_CORNER_SW (1 << 3)
96#define ISO_NUM_CORNER_MASKS 16
98#define ISO_NUM_MASKS (ISO_NUM_EDGE_MASKS + ISO_NUM_CORNER_MASKS)
99
100/* Projection presets */
101
103#define ISO_PROJ_CLASSIC 0
105#define ISO_PROJ_ISOMETRIC 1
107#define ISO_PROJ_MILITARY 2
109#define ISO_PROJ_STAGGERED 3
111#define ISO_NUM_PROJECTIONS 4
112
113/* Legacy aliases */
115#define ISO_PROJ_STEEP ISO_PROJ_ISOMETRIC
117#define ISO_PROJ_WIDE ISO_PROJ_STAGGERED
118
119/* New height-aware isometric data structures (no Allegro dependency) */
120
122#define ISO_MAX_SEGMENTS_PER_TILE 2
123
131
138
141typedef struct ISO_DRAW_ENTRY {
142 int mx, my;
144 int bottom;
145 int top;
148
152typedef struct ISO_PROJECTION {
153 float half_w;
154 float half_h;
155 float angle_deg;
156 float tile_lift;
160
161/* 2D Isometric Camera
162 * Manages camera position, zoom, and coordinate conversion between
163 * screen pixels and world coordinates. Works with iso_map_draw()
164 * and iso_screen_to_map_height() using the library coordinate system.
165 */
166
168typedef struct N_ISO_CAMERA {
169 float x;
170 float y;
171 float zoom;
172 float zoom_min;
173 float zoom_max;
175
179typedef struct ISO_MAP {
180 int width;
181 int height;
185 int* terrain;
187 int* ability;
188 int* overlay;
193
196 /* rendering flags (used by iso_map_draw) */
203 /* height-based ambient tinting */
208 /* neighbor edge heights for chunked rendering */
217
218 /* neighbor edge terrains for chunked transition masks
219 * When a tile sits at a chunk edge, iso_map_calc_transitions_full
220 * needs to know the terrain type on the far side to decide whether
221 * to blit a bleed mask. Without these, the out-of-bounds terrain
222 * lookup returns 0 (water), so every cross-chunk transition is
223 * silently dropped and a hard diagonal seam appears along the
224 * chunk boundary. NULL means the chunk is on the world boundary
225 * or the neighbor is not resident; callers fall back to the
226 * previous "treat as base" behaviour. */
237
243
256} ISO_MAP;
257
258/* New height-aware isometric API (Articles 747/748/934/1269/2026)
259 * These functions do NOT require Allegro.
260 */
261
263ISO_MAP* iso_map_new(int width, int height, int num_terrains, int max_height);
265void iso_map_free(ISO_MAP** map);
266
268void iso_map_set_projection(ISO_MAP* map, int preset, float tile_width);
270void iso_map_set_projection_custom(ISO_MAP* map, float half_w, float half_h, float tile_lift);
272void iso_map_set_projection_target(ISO_MAP* map, int preset);
274void iso_map_lerp_projection(ISO_MAP* map, float dt);
276const char* iso_projection_name(int preset);
277
279int iso_map_get_terrain(const ISO_MAP* map, int mx, int my);
281void iso_map_set_terrain(ISO_MAP* map, int mx, int my, int terrain);
283int iso_map_get_height(const ISO_MAP* map, int mx, int my);
285void iso_map_set_height(ISO_MAP* map, int mx, int my, int h);
287int iso_map_get_ability(const ISO_MAP* map, int mx, int my);
289void iso_map_set_ability(ISO_MAP* map, int mx, int my, int ab);
290
292void iso_map_to_screen(const ISO_MAP* map, int mx, int my, int h, float* screen_x, float* screen_y);
294void iso_screen_to_map(const ISO_MAP* map, float screen_x, float screen_y, int* mx, int* my);
296void iso_map_to_screen_f(const ISO_MAP* map, float fmx, float fmy, float h, float* screen_x, float* screen_y);
301void iso_corner_to_screen(const ISO_MAP* map, int cx, int cy, float fh, float cam_x, float cam_y, float zoom, float* sx, float* sy);
305void iso_screen_to_map_height(const ISO_MAP* map, float screen_x, float screen_y, int tile_w, int tile_h, int* mx, int* my);
309void iso_screen_to_map_height_f(const ISO_MAP* map, float screen_x, float screen_y, int tile_w, int tile_h, int* mx, int* my, float* out_fx, float* out_fy);
310
312int iso_is_in_diamond(int px, int py, int tile_w, int tile_h);
314float iso_diamond_dist(int px, int py, int tile_w, int tile_h);
315
317float iso_map_interpolate_height(const ISO_MAP* map, float fx, float fy);
318
320void iso_map_calc_transitions(const ISO_MAP* map, int mx, int my, int* edge_bits, int* corner_bits);
322int iso_map_should_transition(const ISO_MAP* map, int mx1, int my1, int mx2, int my2);
323
325void iso_map_corner_heights(const ISO_MAP* map, int mx, int my, float* h_n, float* h_e, float* h_s, float* h_w);
326
328int iso_map_save(const ISO_MAP* map, const char* filename);
330ISO_MAP* iso_map_load(const char* filename);
331
333void iso_map_randomize(ISO_MAP* map);
334
335#ifdef N_ASTAR_H
340ASTAR_GRID* iso_map_to_astar_grid(const ISO_MAP* map, int max_height_diff, int start_x, int start_y);
341#endif
342
344void iso_map_smooth_corner_heights(const ISO_MAP* map, int mx, int my, float* h_n, float* h_e, float* h_s, float* h_w);
345
354int iso_map_set_segments(ISO_MAP* map, int mx, int my, const ISO_TILE_SEGMENT* segs, int count);
355
357const ISO_TILE_SEGMENTS* iso_map_get_segments(const ISO_MAP* map, int mx, int my);
358
366int iso_map_build_draw_order(const ISO_MAP* map, ISO_DRAW_ENTRY* out, int max_entries);
367
369int iso_map_should_transition_smooth(const ISO_MAP* map, int mx1, int my1, int mx2, int my2);
370
373void iso_map_calc_transitions_full(const ISO_MAP* map, int mx, int my, int* edge_bits, int* corner_bits);
374
375/* Height border edge visibility
376 * Determines which diamond edges of an elevated tile should be outlined.
377 * An edge is drawn when the adjacent tile has a height difference > 1
378 * or does not exist (map boundary).
379 */
380
393
404ISO_VISIBLE_EDGES iso_map_get_visible_edges(const ISO_MAP* map, int mx, int my);
405
416ISO_VISIBLE_EDGES iso_map_get_visible_edges_segment(const ISO_MAP* map, int mx, int my, int seg_idx);
417
418/* N_ISO_CAMERA API
419 * 2D camera management for isometric viewports. Coordinates match the
420 * library convention used by iso_map_to_screen() and iso_map_draw().
421 */
422
427N_ISO_CAMERA* n_iso_camera_new(float zoom_min, float zoom_max);
428
431
433void n_iso_camera_scroll(N_ISO_CAMERA* cam, float dx, float dy);
434
440void n_iso_camera_zoom(N_ISO_CAMERA* cam, float dz, float mouse_x, float mouse_y);
441
448void n_iso_camera_center_on(N_ISO_CAMERA* cam, float world_x, float world_y, int screen_w, int screen_h);
449
458void n_iso_camera_follow(N_ISO_CAMERA* cam, float target_x, float target_y, int screen_w, int screen_h, float smoothing, float dt);
459
466void n_iso_camera_screen_to_world(const N_ISO_CAMERA* cam, float sx, float sy, float* wx, float* wy);
467
474void n_iso_camera_world_to_screen(const N_ISO_CAMERA* cam, float wx, float wy, float* sx, float* sy);
475
476/* Isometric drawable object for depth-sorted rendering
477 * Objects are interleaved with tiles during iso_map_draw() based on
478 * their map position, achieving correct painter's algorithm ordering.
479 * When an object is behind a taller tile, it can optionally be redrawn
480 * as a transparent overlay so the player can still see it.
481 */
482
489typedef void (*N_ISO_OBJECT_DRAW_FN)(float screen_x, float screen_y, float zoom, float alpha, void* user_data);
490
504
505/* ISO_MAP rendering API (requires Allegro 5)
506 * Provides full isometric rendering with height, terrain transitions,
507 * cliff walls, hover highlight, and grid overlay. Requires pre-generated
508 * tile bitmaps and transition mask overlays from the application.
509 */
510#ifdef HAVE_ALLEGRO
511
512#include <allegro5/allegro.h>
513#include <allegro5/allegro_primitives.h>
514#include <allegro5/allegro_font.h>
515
535void iso_map_draw(const ISO_MAP* map,
536 ALLEGRO_BITMAP** tile_bitmaps,
537 ALLEGRO_BITMAP*** transition_tiles,
538 int num_masks,
539 ALLEGRO_BITMAP** overlay_bitmaps,
540 int num_overlay_tiles,
541 float cam_px,
542 float cam_py,
543 float zoom,
544 int screen_w,
545 int screen_h,
546 int player_mode,
547 N_ISO_OBJECT* objects,
548 int num_objects);
549
556void iso_mask_tile_to_diamond(ALLEGRO_BITMAP* bmp, int tile_w, int tile_h);
557
564void iso_generate_transition_masks(ALLEGRO_BITMAP** masks, int tile_w, int tile_h);
565
576void iso_generate_transition_tiles(ALLEGRO_BITMAP*** tiles,
577 ALLEGRO_BITMAP** masks,
578 ALLEGRO_BITMAP** tile_bitmaps,
579 int num_terrains,
580 int tile_w,
581 int tile_h);
582
604extern double n_iso_pass1_us;
605extern double n_iso_pass2_us;
606extern double n_iso_pass3_us;
607/* Pre-pass setup cost inside iso_map_draw: draw_order alloc +
608 * iso_map_build_draw_order + object screen-pos compute + insertion
609 * sort. Surfaced separately from Pass 1/2/3 because in profiled runs
610 * this section can be > 50 % of the total iso_map_draw cost when
611 * objects are dense. */
612extern double n_iso_setup_us;
613
623typedef ALLEGRO_COLOR (*IsoPrimitiveColorFilter)(ALLEGRO_COLOR c);
625ALLEGRO_COLOR iso_apply_primitive_color_filter(ALLEGRO_COLOR c);
626
627/* Per-frame callback that returns the screen-space (dx, dy) offset
628 * which the consumer has added to its world camera AFTER the iso
629 * engine's `cam_px / cam_py` were sampled (e.g. a temporal-AA
630 * sub-pixel jitter applied on top of the camera snap). The engine
631 * subtracts this offset from the endpoints of every decorative line
632 * draw (cliff-base edge lines in `_draw_segment_sides`; top-face
633 * edges, vertical corner lines, and underside borders in
634 * `_draw_height_borders`) so those lines stay pixel-stable across
635 * frames while filled polygon faces and bitmap sprites continue to
636 * inherit the jitter (which is what drives the temporal-AA averaging
637 * on bitmap content). Without the compensation, thin anti-aliased
638 * lines hit a different sub-pixel position each frame; the
639 * rasterizer's AA coverage flickers; any temporal blend downstream
640 * (TAA's history-weight composite) then averages two slightly
641 * offset semi-transparent lines into visible grey/white pixels along
642 * the line.
643 *
644 * Default NULL = no compensation. Consumers without a jitter source
645 * pay nothing. The callback is invoked per-tile during
646 * `iso_map_draw` (potentially hundreds of times per frame), so it
647 * must be O(1): typically returns the cached jitter from a
648 * `_begin_frame` call elsewhere. Returning (0, 0) is the "no
649 * compensation this frame" signal and is the expected steady state
650 * when the jitter source is off (e.g. camera stationary, TAA
651 * disabled). */
652typedef void (*IsoLineJitterCompensationFn)(float* out_dx, float* out_dy);
654void iso_apply_line_jitter_compensation(float* out_dx, float* out_dy);
655
656#endif /* HAVE_ALLEGRO */
657
662#ifdef __cplusplus
663}
664#endif
665
666#endif /* #ifndef NILOREA_ISOMETRIC_ENGINE */
static int player_mode
Definition ex_gui.c:60
static ALLEGRO_BITMAP * transition_tiles[8][(16+16)]
static int screen_w
static ALLEGRO_BITMAP * tile_bitmaps[8]
static int screen_h
Grid structure holding walkability, costs, and dimensions.
Definition n_astar.h:153
int bottom
segment bottom height (primary sort key)
float fz
height in map units (elevation)
ISO_TILE_SEGMENT segs[2]
int * neighbor_heights_west
Heights from west neighbor chunk's east edge [height], NULL = boundary.
float fy
fractional map Y position
int lower_tile
terrain index for wall/side faces (-1 = use tile's terrain layer)
int * ability
walkability per cell [height * width] (WALK/SWIM/BLCK)
int height
map height in tiles (Y axis)
float occluded_alpha
overlay alpha when behind tiles [0..1], 0=hidden, 0.35=ghost, 1=always visible
int upper_tile
terrain index for top face (-1 = use tile's terrain layer)
int draw_order_dirty
int neighbor_top_se
top height of SE neighbor (0 if absent/boundary)
float tile_lift
vertical pixel offset per height unit
float zoom_min
minimum allowed zoom
int * neighbor_heights_east
Heights from east neighbor chunk's west edge [height], NULL = boundary.
int draw_sw
1 if SW edge (S->W, bottom-left) should be drawn
int neighbor_top_sw
top height of SW neighbor (0 if absent/boundary)
float angle_deg
current projection angle in degrees
int smooth_height
0 = CUT mode (cliff walls), 1 = SMOOTH mode (per-corner slopes)
int * neighbor_terrains_north
[width], terrain of north neighbor's south edge
ISO_DRAW_ENTRY * cached_draw_order
Cached draw_order.
float half_w
half-width of a tile in pixels (horizontal extent)
int count
0..ISO_MAX_SEGMENTS_PER_TILE
int bottom
lower height bound (inclusive), must be < top
int hover_mx
hovered tile X (-1 = none)
int max_height
maximum allowed height value
int top
segment top height
float sprite_h
entity height in world units for occlusion (derived from sprite hot_y)
int seg_idx
segment index within tile (0..count-1)
int draw_nw
1 if NW edge (N->W, top-left) should be drawn
int underside
1 if underside face should be drawn
int neighbor_top_ne
top height of NE neighbor (0 if absent/boundary)
float occlude_clip_y
OUTPUT: screen Y of top occluder north vertex (for cross-chunk clip fallback)
int num_terrains
number of terrain types used
float * dynamic_light_map
Per-tile dynamic light accumulation buffer.
int top
upper height bound, must be > bottom
int * neighbor_terrains_east
[height], terrain of east neighbor's west edge
float half_h
half-height of a tile in pixels (vertical extent)
int * overlay
overlay tile index per cell [height * width], 0 = none.
float lerp_speed
interpolation speed factor (default 3.0)
int neighbor_top_nw
top height of NW neighbor (0 if absent/boundary)
float fx
fractional map X position
int * neighbor_terrains_west
[height], terrain of west neighbor's east edge
void * user_data
user data passed to draw callback
int * neighbor_terrains_south
[width], terrain of south neighbor's north edge
int * neighbor_heights_south
Heights from south neighbor chunk's north edge [width], NULL = boundary.
int * terrain
terrain type per cell [height * width], indices 0..num_terrains-1
N_ISO_OBJECT_DRAW_FN draw
draw callback
float zoom_max
maximum allowed zoom
int * neighbor_heights_north
Heights from north neighbor chunk's south edge [width], NULL = boundary.
float height_tint_intensity
0.0 = no tint, 0.3 = subtle, 1.0 = full range.
float zoom
zoom factor (1.0 = no zoom)
float ambient_b
int is_occluded
OUTPUT: set to 1 if behind tiles during last iso_map_draw() call.
int draw_se
1 if SE edge (E->S, bottom-right) should be drawn
int my
tile coordinates
int cached_draw_order_count
int * heightmap
height value per cell [height * width], 0..max_height
float y
camera Y offset (world units, pre-zoom)
float ambient_r
Global ambient color (day/night + dark place tinting).
int width
map width in tiles (X axis)
float ambient_g
int show_grid
1 = draw grid overlay
float target_angle
target angle for smooth interpolation (degrees)
int draw_ne
1 if NE edge (N->E, top-right) should be drawn
ISO_TILE_SEGMENTS * segments
Per-cell height segments.
float sprite_half_w
entity half-width in screen pixels for horizontal occlusion test
int draw_underside
1 if floating segment underside border should be drawn
int smooth_slope_max
max height diff rendered as slope (default 1)
int hover_my
hovered tile Y (-1 = none)
int cached_draw_order_cap
float x
camera X offset (world units, pre-zoom)
ISO_PROJECTION proj
current projection parameters
double n_iso_pass1_us
Per-pass timing accumulators populated by iso_map_draw.
void iso_map_set_height(ISO_MAP *map, int mx, int my, int h)
set height for a cell (bounds-checked, clamped)
void iso_map_set_projection_custom(ISO_MAP *map, float half_w, float half_h, float tile_lift)
set custom projection parameters directly
ALLEGRO_COLOR(* IsoPrimitiveColorFilter)(ALLEGRO_COLOR c)
Optional design-RGB to display-RGB filter applied to every primitive color (filled polygons,...
void iso_map_smooth_corner_heights(const ISO_MAP *map, int mx, int my, float *h_n, float *h_e, float *h_s, float *h_w)
compute smooth corner heights with slope clamping (for rendering)
double n_iso_setup_us
ISO_MAP * iso_map_new(int width, int height, int num_terrains, int max_height)
create a new height-aware ISO_MAP with given dimensions
float iso_diamond_dist(int px, int py, int tile_w, int tile_h)
distance from pixel to diamond edge (0 at edge, 1 at center)
double n_iso_pass2_us
int iso_map_set_segments(ISO_MAP *map, int mx, int my, const ISO_TILE_SEGMENT *segs, int count)
set per-tile segments on an ISO_MAP.
void n_iso_camera_zoom(N_ISO_CAMERA *cam, float dz, float mouse_x, float mouse_y)
Zoom the camera toward a screen-space point (e.g.
void n_iso_camera_center_on(N_ISO_CAMERA *cam, float world_x, float world_y, int screen_w, int screen_h)
Center the camera so that a world point is at screen center.
double n_iso_pass3_us
int iso_map_save(const ISO_MAP *map, const char *filename)
save ISO_MAP to binary file (chunk-based format)
ALLEGRO_COLOR iso_apply_primitive_color_filter(ALLEGRO_COLOR c)
int iso_map_should_transition_smooth(const ISO_MAP *map, int mx1, int my1, int mx2, int my2)
check if terrain transition should render between two cells (height-aware)
void iso_corner_to_screen(const ISO_MAP *map, int cx, int cy, float fh, float cam_x, float cam_y, float zoom, float *sx, float *sy)
Project a tile corner to screen coordinates (canonical formula).
void iso_set_line_jitter_compensation(IsoLineJitterCompensationFn fn)
void iso_map_lerp_projection(ISO_MAP *map, float dt)
smoothly interpolate current projection angle toward target (call every frame)
#define ISO_MAX_SEGMENTS_PER_TILE
Max height segments per tile (ground + one elevated structure).
void iso_mask_tile_to_diamond(ALLEGRO_BITMAP *bmp, int tile_w, int tile_h)
Mask a tile bitmap to the isometric diamond shape.
ISO_VISIBLE_EDGES iso_map_get_visible_edges(const ISO_MAP *map, int mx, int my)
Compute which diamond edges of tile (mx, my) need a height border.
ISO_MAP * iso_map_load(const char *filename)
load ISO_MAP from binary file
void n_iso_camera_free(N_ISO_CAMERA **cam)
Free a camera and set the pointer to NULL.
int iso_map_build_draw_order(const ISO_MAP *map, ISO_DRAW_ENTRY *out, int max_entries)
Build the draw order for segment-sorted rendering.
int iso_map_should_transition(const ISO_MAP *map, int mx1, int my1, int mx2, int my2)
check if terrain blending should occur between two adjacent cells
const char * iso_projection_name(int preset)
get the display name for a projection preset
void n_iso_camera_follow(N_ISO_CAMERA *cam, float target_x, float target_y, int screen_w, int screen_h, float smoothing, float dt)
Smoothly follow a world-space target (camera lerp).
void iso_map_set_ability(ISO_MAP *map, int mx, int my, int ab)
set ability for a cell (bounds-checked)
ISO_VISIBLE_EDGES iso_map_get_visible_edges_segment(const ISO_MAP *map, int mx, int my, int seg_idx)
Compute per-segment edge visibility for height border rendering.
int iso_map_get_terrain(const ISO_MAP *map, int mx, int my)
get terrain type for a cell (bounds-checked)
void iso_map_calc_transitions_full(const ISO_MAP *map, int mx, int my, int *edge_bits, int *corner_bits)
compute per-terrain transition bitmasks with height filtering (Article 934).
int iso_map_get_ability(const ISO_MAP *map, int mx, int my)
get ability for a cell (bounds-checked)
void iso_map_draw(const ISO_MAP *map, ALLEGRO_BITMAP **tile_bitmaps, ALLEGRO_BITMAP ***transition_tiles, int num_masks, ALLEGRO_BITMAP **overlay_bitmaps, int num_overlay_tiles, float cam_px, float cam_py, float zoom, int screen_w, int screen_h, int player_mode, N_ISO_OBJECT *objects, int num_objects)
Draw the full ISO_MAP with height, transitions, overlays, cliff walls, hover, and grid.
void iso_map_to_screen(const ISO_MAP *map, int mx, int my, int h, float *screen_x, float *screen_y)
convert map tile coordinates to screen pixel coordinates
void iso_map_calc_transitions(const ISO_MAP *map, int mx, int my, int *edge_bits, int *corner_bits)
compute terrain transition bitmasks for a cell (Article 934)
void iso_map_set_projection(ISO_MAP *map, int preset, float tile_width)
set projection preset and snap to it immediately
void n_iso_camera_screen_to_world(const N_ISO_CAMERA *cam, float sx, float sy, float *wx, float *wy)
Convert screen pixel coordinates to world coordinates.
void iso_map_to_screen_f(const ISO_MAP *map, float fmx, float fmy, float h, float *screen_x, float *screen_y)
convert map tile coordinates to screen pixel coordinates (float version)
void iso_map_free(ISO_MAP **map)
free an ISO_MAP and set the pointer to NULL
int iso_is_in_diamond(int px, int py, int tile_w, int tile_h)
test if pixel (px,py) is inside the isometric diamond of size tile_w x tile_h
void iso_generate_transition_tiles(ALLEGRO_BITMAP ***tiles, ALLEGRO_BITMAP **masks, ALLEGRO_BITMAP **tile_bitmaps, int num_terrains, int tile_w, int tile_h)
Pre-composite transition tiles (terrain texture * alpha mask).
void iso_map_set_projection_target(ISO_MAP *map, int preset)
set target projection preset for smooth interpolation via iso_map_lerp_projection
void iso_set_primitive_color_filter(IsoPrimitiveColorFilter fn)
void iso_map_set_terrain(ISO_MAP *map, int mx, int my, int terrain)
set terrain type for a cell (bounds-checked)
void iso_screen_to_map(const ISO_MAP *map, float screen_x, float screen_y, int *mx, int *my)
convert screen pixel coordinates to map tile coordinates (flat, no height)
void iso_map_randomize(ISO_MAP *map)
randomize terrain and height for testing/demo purposes
void iso_generate_transition_masks(ALLEGRO_BITMAP **masks, int tile_w, int tile_h)
Generate the 32 procedural transition alpha masks (16 edge + 16 corner).
void(* IsoLineJitterCompensationFn)(float *out_dx, float *out_dy)
void(* N_ISO_OBJECT_DRAW_FN)(float screen_x, float screen_y, float zoom, float alpha, void *user_data)
Object draw callback.
const ISO_TILE_SEGMENTS * iso_map_get_segments(const ISO_MAP *map, int mx, int my)
get per-tile segments.
int iso_map_get_height(const ISO_MAP *map, int mx, int my)
get height for a cell (bounds-checked, clamped)
float iso_map_interpolate_height(const ISO_MAP *map, float fx, float fy)
bilinear height interpolation at fractional map coordinates
void n_iso_camera_world_to_screen(const N_ISO_CAMERA *cam, float wx, float wy, float *sx, float *sy)
Convert world coordinates to screen pixel coordinates.
void iso_screen_to_map_height_f(const ISO_MAP *map, float screen_x, float screen_y, int tile_w, int tile_h, int *mx, int *my, float *out_fx, float *out_fy)
height-aware screen-to-map conversion returning fractional tile coordinates.
void iso_screen_to_map_height(const ISO_MAP *map, float screen_x, float screen_y, int tile_w, int tile_h, int *mx, int *my)
height-aware screen-to-map conversion with diamond hit testing.
void iso_map_corner_heights(const ISO_MAP *map, int mx, int my, float *h_n, float *h_e, float *h_s, float *h_w)
compute average corner heights for smooth rendering (Article 2026)
void iso_apply_line_jitter_compensation(float *out_dx, float *out_dy)
void n_iso_camera_scroll(N_ISO_CAMERA *cam, float dx, float dy)
Scroll the camera by (dx, dy) world units.
N_ISO_CAMERA * n_iso_camera_new(float zoom_min, float zoom_max)
Create a new camera with the given zoom limits.
Draw order entry for segment-sorted rendering.
Height-aware isometric map with terrain and height layers, per-cell height values,...
Axonometric projection parameters.
Single vertical segment of a tile: solid matter from bottom to top.
Per-tile height segments.
Per-tile edge visibility flags for height border rendering.
2D isometric camera for viewport management.
Drawable object for depth-sorted isometric rendering.
Common headers and low-level functions & define.
Generic log system.