void draw_map(int cx, int cy) { int x, y, symcount, attr, cursx, cursy; unsigned int frame; struct curses_symdef syms[4]; if (!display_buffer || !mapwin) return; getyx(mapwin, cursy, cursx); frame = 0; if (settings.blink) frame = get_milliseconds() / 666; for (y = 0; y < ROWNO; y++) { for (x = 1; x < COLNO; x++) { int bg_color = 0; /* set the position for each character to prevent incorrect positioning due to charset issues (IBM chars on a unicode term or vice versa) */ wmove(mapwin, y, x - 1); symcount = mapglyph(&display_buffer[y][x], syms, &bg_color); attr = A_NORMAL; if (!(COLOR_PAIRS >= 113 || (COLORS < 16 && COLOR_PAIRS >= 57))) { /* we don't have background colors available */ bg_color = 0; if (((display_buffer[y][x].monflags & MON_TAME) && settings.hilite_pet) || ((display_buffer[y][x].monflags & MON_DETECTED) && settings.use_inverse)) attr |= A_REVERSE; } else if (bg_color == 0) { /* we do have background colors available */ if ((display_buffer[y][x].monflags & MON_DETECTED) && settings.use_inverse) bg_color = CLR_MAGENTA; if ((display_buffer[y][x].monflags & MON_PEACEFUL) && settings.hilite_pet) bg_color = CLR_BROWN; if ((display_buffer[y][x].monflags & MON_TAME) && settings.hilite_pet) bg_color = CLR_BLUE; } print_sym(mapwin, &syms[frame % symcount], attr, bg_color); } } wmove(mapwin, cursy, cursx); wnoutrefresh(mapwin); }
/* * Allocate a cache slot for the given glyph. Note, this may evict an entry * if the cache is full. */ int nds_allocate_cache_slot(coord_t coords) { int glyph = map->glyphs[coords.y][coords.x]; int cache_slot = -1; int i; int oldest_diff = 0; int oldest; int ch, colour; unsigned int special; for (i = 0; i < map->num_cache_entries; i++) { int diff; if (map->tile_cache[i].glyph < 0) { cache_slot = i; break; } else if (map->tile_cache[i].last_used < 0) { continue; } diff = moves - map->tile_cache[i].last_used; if (diff > oldest_diff) { oldest = i; oldest_diff = diff; } } if (cache_slot < 0) { cache_slot = oldest; } mapglyph(glyph, &ch, &colour, &special, coords.x, coords.y); map->tile_cache[cache_slot].glyph = glyph; map->tile_cache[cache_slot].colour = colour; map->tile_cache[cache_slot].special = special; map->tile_cache[cache_slot].ch = ch; map->tile_cache[cache_slot].tile = glyph2tile[glyph]; return cache_slot; }
/* * Returns the cache slot number for the given glyph, if one exists. */ int nds_find_cache_slot(coord_t coords) { int glyph = map->glyphs[coords.y][coords.x]; int i; int ch, colour; unsigned int special; int tile = glyph2tile[glyph]; mapglyph(glyph, &ch, &colour, &special, coords.x, coords.y); for (i = 0; i < map->num_cache_entries; i++) { if ((map->tile_cache[i].glyph == glyph) && (map->tile_cache[i].colour == colour) && (map->tile_cache[i].special == special) && (map->tile_cache[i].ch == ch) && (map->tile_cache[i].tile == tile)) { return i; } } return -1; }
/* print_glyph(window, x, y, glyph) -- Print the glyph at (x,y) on the given window. Glyphs are integers at the interface, mapped to whatever the window- port wants (symbol, font, color, attributes, ...there's a 1-1 map between glyphs and distinct things on the map). */ void curses_print_glyph(winid wid, xchar x, xchar y, int glyph) { int ch, color; unsigned int special; int attr = -1; /* map glyph to character and color */ mapglyph(glyph, (glyph_t*)&ch, &color, &special, x, y); if ((special & MG_PET) && iflags.hilite_pet) { attr = iflags.wc2_petattr; } if ((special & MG_DETECT) && iflags.use_inverse) { attr = A_REVERSE; } if (iflags.cursesgraphics) { ch = curses_convert_glyph(ch, glyph); } curses_putch(wid, x, y, ch, color, attr); }
/* on WM_PAINT */ void onPaint(HWND hWnd) { PNHMapWindow data; PAINTSTRUCT ps; HDC hDC; HDC tileDC; HGDIOBJ saveBmp; RECT paint_rt; int i, j; /* get window data */ data = (PNHMapWindow) GetWindowLong(hWnd, GWL_USERDATA); hDC = BeginPaint(hWnd, &ps); /* calculate paint rectangle */ if (!IsRectEmpty(&ps.rcPaint)) { /* calculate paint rectangle */ paint_rt.left = max(data->xPos + (ps.rcPaint.left - data->map_orig.x) / data->xScrTile, 0); paint_rt.top = max( data->yPos + (ps.rcPaint.top - data->map_orig.y) / data->yScrTile, 0); paint_rt.right = min( data->xPos + (ps.rcPaint.right - data->map_orig.x) / data->xScrTile + 1, COLNO); paint_rt.bottom = min( data->yPos + (ps.rcPaint.bottom - data->map_orig.y) / data->yScrTile + 1, ROWNO); if (data->bAsciiMode || Is_rogue_level(&u.uz)) { /* You enter a VERY primitive world! */ HGDIOBJ oldFont; oldFont = SelectObject(hDC, data->hMapFont); SetBkMode(hDC, TRANSPARENT); /* draw the map */ for (i = paint_rt.left; i < paint_rt.right; i++) for (j = paint_rt.top; j < paint_rt.bottom; j++) if (data->map[i][j] >= 0) { char ch; TCHAR wch; RECT glyph_rect; int color; unsigned special; int mgch; HBRUSH back_brush; COLORREF OldFg; nhcoord2display(data, i, j, &glyph_rect); #if (VERSION_MAJOR < 4) && (VERSION_MINOR < 4) && (PATCHLEVEL < 2) nhglyph2charcolor(data->map[i][j], &ch, &color); OldFg = SetTextColor(hDC, nhcolor_to_RGB(color)); #else /* rely on NetHack core helper routine */ (void) mapglyph(data->map[i][j], &mgch, &color, &special, i, j); ch = (char) mgch; if (((special & MG_PET) && iflags.hilite_pet) || ((special & MG_DETECT) && iflags.use_inverse)) { back_brush = CreateSolidBrush(nhcolor_to_RGB(CLR_GRAY)); FillRect(hDC, &glyph_rect, back_brush); DeleteObject(back_brush); switch (color) { case CLR_GRAY: case CLR_WHITE: OldFg = SetTextColor( hDC, nhcolor_to_RGB(CLR_BLACK)); break; default: OldFg = SetTextColor(hDC, nhcolor_to_RGB(color)); } } else { OldFg = SetTextColor(hDC, nhcolor_to_RGB(color)); } #endif DrawText(hDC, NH_A2W(&ch, &wch, 1), 1, &glyph_rect, DT_CENTER | DT_VCENTER | DT_NOPREFIX); SetTextColor(hDC, OldFg); } SelectObject(hDC, oldFont); } else { /* prepare tiles DC for mapping */ tileDC = CreateCompatibleDC(hDC); saveBmp = SelectObject(tileDC, GetNHApp()->bmpMapTiles); /* draw the map */ for (i = paint_rt.left; i < paint_rt.right; i++) for (j = paint_rt.top; j < paint_rt.bottom; j++) if (data->map[i][j] >= 0) { short ntile; int t_x, t_y; RECT glyph_rect; ntile = glyph2tile[data->map[i][j]]; t_x = (ntile % GetNHApp()->mapTilesPerLine) * GetNHApp()->mapTile_X; t_y = (ntile / GetNHApp()->mapTilesPerLine) * GetNHApp()->mapTile_Y; nhcoord2display(data, i, j, &glyph_rect); StretchBlt(hDC, glyph_rect.left, glyph_rect.top, data->xScrTile, data->yScrTile, tileDC, t_x, t_y, GetNHApp()->mapTile_X, GetNHApp()->mapTile_Y, SRCCOPY); if (glyph_is_pet(data->map[i][j]) && iflags.wc_hilite_pet) { /* apply pet mark transparently over pet image */ HDC hdcPetMark; HBITMAP bmPetMarkOld; /* this is DC for petmark bitmap */ hdcPetMark = CreateCompatibleDC(hDC); bmPetMarkOld = SelectObject( hdcPetMark, GetNHApp()->bmpPetMark); nhapply_image_transparent( hDC, glyph_rect.left, glyph_rect.top, data->xScrTile, data->yScrTile, hdcPetMark, 0, 0, TILE_X, TILE_Y, TILE_BK_COLOR); SelectObject(hdcPetMark, bmPetMarkOld); DeleteDC(hdcPetMark); } } SelectObject(tileDC, saveBmp); DeleteDC(tileDC); } /* draw focus rect */ nhcoord2display(data, data->xCur, data->yCur, &paint_rt); if (data->bAsciiMode) { PatBlt(hDC, paint_rt.left, paint_rt.top, paint_rt.right - paint_rt.left, paint_rt.bottom - paint_rt.top, DSTINVERT); } else { DrawFocusRect(hDC, &paint_rt); } } EndPaint(hWnd, &ps); }