![]() |
Nilorea Library
C utilities for networking, threading, graphics
|
Isometric/axonometric tile engine with height maps, terrain transitions, and A* pathfinding integration. More...
#include <math.h>#include <stdio.h>#include "nilorea/n_astar.h"#include "nilorea/n_iso_engine.h"#include <allegro5/allegro.h>#include <allegro5/allegro_primitives.h>
Include dependency graph for n_iso_engine.c:Go to the source code of this file.
Functions | |
| static int | _cmp_draw_entry (const void *a, const void *b) |
| static ALLEGRO_COLOR | _compute_tile_tint (int seg_top, int max_height, float intensity, float ambient_r, float ambient_g, float ambient_b, float dyn_r, float dyn_g, float dyn_b) |
| static void | _draw_height_borders (const ISO_MAP *map, int mx, int my, int seg_idx, int seg_bottom, int seg_top, int has_underside_face, const float vx[4], const float vy[4], float lift) |
| Draw black border outlines on the diamond edges of an elevated tile. | |
| static void | _draw_segment_sides (const ISO_MAP *map, float east_x, float east_y, float south_x, float south_y, float west_x, float west_y, int mx, int my, int seg_bottom, int seg_top, float lift, float height_brightness, int wall_terrain_override) |
| Draw cliff side faces for a single segment {seg_bottom..seg_top}. | |
| static void | _draw_segment_underside (ALLEGRO_BITMAP *bmp, float base_dx, float base_dy, float phw, float phh, float tile_draw_w, float tile_draw_h, int tile_w, int tile_h) |
| Draw the underside face of a floating segment at 65% brightness. | |
| static void | _draw_tile_warped (ALLEGRO_BITMAP *bmp, const float vx[4], const float vy[4], int tile_w, int tile_h, ALLEGRO_COLOR tint) |
| Draw a tile bitmap warped to 4 pre-computed screen vertices. | |
| static ALLEGRO_COLOR | _height_tint (int seg_top, int max_height, float intensity) |
| Compute a brightness tint color for a segment at a given height. | |
| static void | _iso_corner_to_screen (float hw, float hh, float tl, int cx, int cy, float fh, float cam_px, float cam_py, float zoom, float *sx, float *sy) |
| Project a tile corner to screen coordinates (canonical formula). | |
| static int | _iso_object_check_occlusion (const ISO_MAP *map, float obj_fx, float obj_fy, float obj_fz, float obj_sx, float obj_sy, float sprite_h, float sprite_half_w, float cam_px, float cam_py, float zoom, float *out_clip_y) |
| Check if an object is occluded by tiles drawn in front of it. | |
| static float | _iso_preset_angle (int preset) |
| Get the angle in degrees for a projection preset. | |
| static float | _smooth_neighbor_h (const ISO_MAP *map, float h_self, int nx, int ny) |
| Helper: clamp neighbor height for smooth slope rendering. | |
| static int | _tile_covers_height (const ISO_MAP *map, int mx, int my, int z) |
| Check if a tile has geometry covering height level z. | |
| int | camera_to_map (MAP **map, int tx, int ty, int x, int y) |
| Center Map on given map coordinate, with x & y offset. | |
| int | camera_to_scr (MAP **map, int x, int y) |
| Center Map on given screen coordinate. | |
| int | create_empty_map (MAP **map, const char *name, int XSIZE, int YSIZE, int TILEW, int TILEH, int nbmaxobjects, int nbmaxgroup, int nbmaxanims, int nbtiles, int nbanims) |
| Create an empty map. | |
| int | draw_map (MAP *map, ALLEGRO_BITMAP *bmp, int destx, int desty, int mode) |
| Draw a MAP *map on the ALLEGRO_BITMAP *bmp. | |
| int | free_map (MAP **map) |
| Free the map. | |
| int | get_value (MAP *map, int type, int x, int y) |
| Get a the tilenumber of a cell item. | |
| void | iso_corner_to_screen (const ISO_MAP *map, int cx, int cy, float fh, float cam_px, float cam_py, float zoom, float *sx, float *sy) |
| Project a tile corner to screen coordinates (canonical formula). | |
| float | iso_diamond_dist (int px, int py, int tile_w, int tile_h) |
| Distance from pixel to the diamond edge. | |
| 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 | 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). | |
| 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. | |
| 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. | |
| 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_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. | |
| 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 tile rendering (Article 2026). | |
| 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 segment-sorted rendering. | |
| void | iso_map_free (ISO_MAP **map_ptr) |
| Free an ISO_MAP and set the pointer to NULL. | |
| int | iso_map_get_ability (const ISO_MAP *map, int mx, int my) |
| Get the ability at a cell. | |
| int | iso_map_get_height (const ISO_MAP *map, int mx, int my) |
| Get the height at a cell. | |
| const ISO_TILE_SEGMENTS * | iso_map_get_segments (const ISO_MAP *map, int mx, int my) |
| get per-tile segments. | |
| int | iso_map_get_terrain (const ISO_MAP *map, int mx, int my) |
| Get the terrain type at a cell. | |
| 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_VISIBLE_EDGES | iso_map_get_visible_edges_segment (const ISO_MAP *map, int mx, int my, int seg_idx) |
| Per-segment edge visibility with adjacency + occlusion. | |
| float | iso_map_interpolate_height (const ISO_MAP *map, float fx, float fy) |
| Bilinear height interpolation at fractional map coordinates. | |
| void | iso_map_lerp_projection (ISO_MAP *map, float dt) |
| Smoothly interpolate the projection angle toward the target. | |
| ISO_MAP * | iso_map_load (const char *filename) |
| Load ISO_MAP from a binary file. | |
| ISO_MAP * | iso_map_new (int width, int height, int num_terrains, int max_height) |
| Create a new height-aware isometric map. | |
| void | iso_map_randomize (ISO_MAP *map) |
| Randomize terrain and height for testing/demo purposes. | |
| int | iso_map_save (const ISO_MAP *map, const char *filename) |
| Save ISO_MAP to a binary file. | |
| void | iso_map_set_ability (ISO_MAP *map, int mx, int my, int ab) |
| Set the ability at a cell. | |
| void | iso_map_set_height (ISO_MAP *map, int mx, int my, int h) |
| Set the height at a cell (clamped to [0, max_height]) | |
| void | iso_map_set_projection (ISO_MAP *map, int preset, float tile_width) |
| Set projection parameters from a preset and tile width. | |
| void | iso_map_set_projection_custom (ISO_MAP *map, float half_w, float half_h, float tile_lift) |
| Set custom projection parameters directly. | |
| void | iso_map_set_projection_target (ISO_MAP *map, int preset) |
| Set the target projection for smooth interpolation. | |
| 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 | iso_map_set_terrain (ISO_MAP *map, int mx, int my, int terrain) |
| Set the terrain type at a cell. | |
| 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. | |
| 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_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. | |
| 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_to_screen_f (const ISO_MAP *map, float fmx, float fmy, float h, float *screen_x, float *screen_y) |
| Convert map coordinates to screen coordinates (float version). | |
| void | iso_mask_tile_to_diamond (ALLEGRO_BITMAP *bmp, int tile_w, int tile_h) |
| Mask a tile bitmap to the isometric diamond shape. | |
| const char * | iso_projection_name (int preset) |
| Get the display name for a projection preset. | |
| 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. | |
| 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_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. | |
| int | load_map (MAP **map, char *filename) |
| Load the map from filename. | |
| 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. | |
| 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. | |
| void | n_iso_camera_free (N_ISO_CAMERA **cam) |
| Free a camera and set the pointer to NULL. | |
| N_ISO_CAMERA * | n_iso_camera_new (float zoom_min, float zoom_max) |
| Create a new 2D isometric camera. | |
| 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 | n_iso_camera_scroll (N_ISO_CAMERA *cam, float dx, float dy) |
| Scroll the camera by (dx, dy) world units. | |
| 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 | n_iso_camera_zoom (N_ISO_CAMERA *cam, float dz, float mouse_x, float mouse_y) |
| Zoom the camera toward a screen-space point. | |
| int | save_map (MAP *map, char *filename) |
| Save the map to filename. | |
| int | ScreenToMap (int mx, int my, int *Tilex, int *Tiley, ALLEGRO_BITMAP *mousemap) |
| Convert screen coordinate to map coordinate. | |
| int | set_value (MAP *map, int type, int x, int y, int value) |
| Set the value of a cell in a map. | |
Isometric/axonometric tile engine with height maps, terrain transitions, and A* pathfinding integration.
Definition in file n_iso_engine.c.
|
static |
Definition at line 1506 of file n_iso_engine.c.
References ISO_DRAW_ENTRY::bottom, ISO_DRAW_ENTRY::mx, and ISO_DRAW_ENTRY::my.
Referenced by iso_map_build_draw_order().
Here is the caller graph for this function:
|
inlinestatic |
Definition at line 2033 of file n_iso_engine.c.
Referenced by iso_map_draw().
Here is the caller graph for this function:
|
static |
Draw black border outlines on the diamond edges of an elevated tile.
Rules:
Diamond vertices: N=vx[0] (top), E=vx[1] (right), S=vx[2] (bottom), W=vx[3] (left)
Definition at line 2348 of file n_iso_engine.c.
References ISO_VISIBLE_EDGES::draw_ne, ISO_VISIBLE_EDGES::draw_nw, ISO_VISIBLE_EDGES::draw_se, ISO_VISIBLE_EDGES::draw_sw, ISO_VISIBLE_EDGES::draw_underside, iso_map_get_visible_edges_segment(), ISO_VISIBLE_EDGES::neighbor_top_ne, ISO_VISIBLE_EDGES::neighbor_top_nw, ISO_VISIBLE_EDGES::neighbor_top_se, and ISO_VISIBLE_EDGES::neighbor_top_sw.
Referenced by iso_map_draw().
Here is the call graph for this function:
Here is the caller graph for this function:
|
static |
Draw cliff side faces for a single segment {seg_bottom..seg_top}.
For ground segments (seg_bottom==0) uses neighbor-aware wall height. For floating segments (seg_bottom>0) draws full segment height.
Definition at line 2123 of file n_iso_engine.c.
References iso_map_get_height(), and iso_map_get_terrain().
Referenced by iso_map_draw().
Here is the call graph for this function:
Here is the caller graph for this function:
|
static |
Draw the underside face of a floating segment at 65% brightness.
The underside is a diamond drawn at the segment's bottom height.
Definition at line 2224 of file n_iso_engine.c.
Referenced by iso_map_draw().
Here is the caller graph for this function:
|
static |
Draw a tile bitmap warped to 4 pre-computed screen vertices.
Uses two textured triangles mapped to the warped diamond shape. Vertices must come from _iso_corner_to_screen for bit-identical shared edges between adjacent tiles.
Definition at line 2067 of file n_iso_engine.c.
Referenced by iso_map_draw().
Here is the caller graph for this function:
|
inlinestatic |
Compute a brightness tint color for a segment at a given height.
Higher segments are brighter (closer to white), lower segments are darker.
| seg_top | top height of the segment |
| max_height | maximum height in the map (0 = no scaling) |
| intensity | tint intensity (0.0 = no tint/white, 1.0 = full range) |
Definition at line 2019 of file n_iso_engine.c.
|
inlinestatic |
Project a tile corner to screen coordinates (canonical formula).
Every screen vertex in the renderer must come from this function so that two tiles sharing a corner get bit-identical screen positions regardless of which tile's draw call is computing the vertex.
The camera offset (cam_px, cam_py) must be integer-snapped pixel offsets computed as floor(cam_x * zoom), floor(cam_y * zoom). This ensures the fractional pixel position of each vertex comes only from (wx * zoom), which is constant per vertex, eliminating sub-pixel aliasing shimmer during camera movement.
| hw | map->proj.half_w (unzoomed) |
| hh | map->proj.half_h (unzoomed) |
| tl | map->proj.tile_lift (unzoomed) |
| cx | corner X in tile grid (e.g. mx+1 for the East corner) |
| cy | corner Y in tile grid |
| fh | height (float, supports smooth-height interpolation) |
| cam_px | integer-snapped camera pixel X: floor(cam_x * zoom) |
| cam_py | integer-snapped camera pixel Y: floor(cam_y * zoom) |
| zoom | zoom factor |
| sx | output screen X |
| sy | output screen Y |
Definition at line 2004 of file n_iso_engine.c.
Referenced by _iso_object_check_occlusion(), and iso_map_draw().
Here is the caller graph for this function:
|
static |
Check if an object is occluded by tiles drawn in front of it.
Tests tiles at higher depth (mx+my) in a forward cone to see if any elevated tile's screen area overlaps the object's screen position.
| map | the map |
| obj_fx | object fractional map X |
| obj_fy | object fractional map Y |
| obj_fz | object height |
| obj_sx | object screen X (camera-transformed) |
| obj_sy | object screen Y (camera-transformed) |
| sprite_h | sprite height used for occlusion bounding |
| cam_px | camera X offset in pixels |
| cam_py | camera Y offset in pixels |
| zoom | current zoom |
Definition at line 2259 of file n_iso_engine.c.
References _iso_corner_to_screen(), ISO_PROJECTION::half_h, ISO_PROJECTION::half_w, ISO_MAP::height, iso_map_get_height(), iso_map_to_screen(), ISO_MAP::max_height, ISO_MAP::proj, ISO_PROJECTION::tile_lift, and ISO_MAP::width.
Referenced by iso_map_draw().
Here is the call graph for this function:
Here is the caller graph for this function:
|
static |
Get the angle in degrees for a projection preset.
| preset | one of ISO_PROJ_CLASSIC, ISO_PROJ_ISOMETRIC, ISO_PROJ_STAGGERED, ISO_PROJ_MILITARY |
Definition at line 696 of file n_iso_engine.c.
References ISO_PROJ_CLASSIC, ISO_PROJ_ISOMETRIC, ISO_PROJ_MILITARY, and ISO_PROJ_STAGGERED.
Referenced by iso_map_set_projection(), and iso_map_set_projection_target().
Here is the caller graph for this function:
|
inlinestatic |
Helper: clamp neighbor height for smooth slope rendering.
If the height difference exceeds smooth_slope_max, return self height (creating a cliff instead of a slope).
Definition at line 1426 of file n_iso_engine.c.
References iso_map_get_height(), and ISO_MAP::smooth_slope_max.
Referenced by iso_map_smooth_corner_heights().
Here is the call graph for this function:
Here is the caller graph for this function:
|
static |
Check if a tile has geometry covering height level z.
Returns 1 if any segment of (mx,my) has bottom <= z AND top > z, meaning the tile's wall/surface extends strictly above z. Used for occlusion: a tile drawn later in painter order covers edges of earlier tiles when its wall passes above the edge height.
Requires the occluding tile to be at least 2 height units taller (top > z + 1) so that single-step stairs (+1 per tile) do not suppress the NW/NE borders — the step only partially covers the edge, and painter order handles the overlap visually.
Definition at line 1824 of file n_iso_engine.c.
References ISO_TILE_SEGMENT::bottom, ISO_TILE_SEGMENTS::count, ISO_MAP::height, iso_map_get_height(), iso_map_get_segments(), ISO_TILE_SEGMENTS::segs, ISO_TILE_SEGMENT::top, and ISO_MAP::width.
Referenced by iso_map_get_visible_edges_segment().
Here is the call graph for this function:
Here is the caller graph for this function: