#include "dclient/widgets/map.h" #include "dclient/render_glyph.h" #include "deliantra/data/glyph.h" #include "deliantra/data/map.h" #include #include #include #define HIGHLIGHT_PLAYER 1 map_widget::map_widget (ndk::panel *parent) : frame ("", parent) , map (nullptr) { } void map_widget::update (data::map const &map) { this->map = ↦ } static u16 select_face (u16 const (&face)[3], int layer) { if (layer == -1) return face[2] ? face[2] : face[1] ? face[1] : face[0] ; return face[layer]; } void map_widget::draw () { frame::draw (); if (!map) return; static int const layer = -1; int const W = (this->width () - 2) / 2; int const H = (this->height () - 2); ndk::pen pen (*this); static data::glyph const space = { { { 0, 0, L' ' }, { 0, 0, L' ' } } }; #if HIGHLIGHT_PLAYER static data::glyph const player = { { { 0, 0, L'@' }, { 13, 13, L'@' } } }; #endif int const zerox = -(W - map->w) / 4 + 1; int const zeroy = -(H - map->h) / 2 + 1; #if HIGHLIGHT_PLAYER int const playerx = W; int const playery = H / 2; #endif for (int y = zeroy; y < H + zeroy; y++) { int const mapy = y + map->y; if (!map->rows.has (mapy)) continue; auto const &row = map->rows[mapy]; for (int x = zerox; x < W + zerox; x++) { int const mapx = x + map->x - 2; if (!row.has (mapx)) continue; data::map::cell const &cell = row[mapx]; u32 const face = select_face (cell.face, layer); data::glyph const *glyph; int const winy = y - zeroy + 1; int const winx = x * 2 - zerox + 1; if (winx == playerx && winy == playery) glyph = &player; else if (face && face < data::glyphs.size ()) // TODO: warn about face >= size glyph = &data::glyphs[face]; else glyph = &space; return_unless (pen.move (winx, winy)); write (pen, *glyph, cell.darkness); } } #if HIGHLIGHT_PLAYER // 19:15 < n0nsense> pippijn: kannst du nethack-mäßig noch den cursor auf den player setzen? if (active ()) { pen.move (playerx, playery); ndk::app->cursor_on (); } else ndk::app->cursor_off (); #endif if (getenv ("DCLIENT_ONESHOT")) { delete ndk::app; exit (0); } pen.set_color ({ }); // reset }