#include #include #include #include "vars.h" #include "util.h" #include "pline.h" #include "scrsyms.h" #include "signals.h" #include "obj-map.h" #include "digspecial.h" #include "stdio-util.h" #include "display.h" static char dc[LEV_X][LEV_Y]; static unsigned char df[LEV_X][LEV_Y]; #define DF_LIT 0x01 static int min_x; static int max_x; static int min_y; static int max_y; /* level = screen - dispo */ /* map = level + mapo */ /* screen = level + dispo */ /* level = map - mapo */ /* dispo = screen - level */ /* mapo = map - level */ int dispox; int dispoy; int mapox; int mapoy; void initdisplay(void) { cleardisp(); } static int empty(LOC *l) { return(l && ((l->type == LOC_CAVE) || (l->type == LOC_GATE))); } static char loc_map_wall(LOC *lc) { LOC *adj[3][3]; LOC *l; int dx; int dy; int x; int y; int syndrome; int b; static const int synbits[3][3] = { { 0x80, 0x40, 0x20 }, { 0x01, 0, 0x10 }, { 0x02, 0x04, 0x08 } }; syndrome = 0; for (dx=0;dx<=2;dx++) { x = lc->x + dx - 1; for (dy=0;dy<=2;dy++) { y = lc->y + dy - 1; if ((x < 0) || (y < 0) || (x >= LEV_X) || (y >= LEV_Y)) { l = 0; } else { l = &lc->on->cells[x][y]; b = synbits[dx][dy]; if ((b & 0x55) && (l->type == LOC_DOOR)) return(SYM_TWALL); if (empty(l)) syndrome += b; } adj[dx+1][dy+1] = l; } } switch (syndrome & 0x55) { case 0x44: return(SYM_VWALL); break; case 0x04: return((syndrome&0xa0)?SYM_TWALL:SYM_VWALL); break; case 0x40: return((syndrome&0x0a)?SYM_TWALL:SYM_VWALL); break; case 0x11: return(SYM_HWALL); break; case 0x01: return((syndrome&0x28)?SYM_TWALL:SYM_HWALL); break; case 0x10: return((syndrome&0x82)?SYM_TWALL:SYM_HWALL); break; } return(SYM_TWALL); } char loc_char(LOC *l, LCHOW how) { switch (l->type) { case LOC_ROCK: return(SYM_ROCK); break; case LOC_SDOOR: if (how == LC_DEBUG) { switch (l->walldoor) { case LOC_UWALL: return(SYM_USDOOR); break; case LOC_HWALL: return(SYM_HSDOOR); break; case LOC_VWALL: return(SYM_VSDOOR); break; case LOC_TWALL: return(SYM_TSDOOR); break; default: return(SYM_UNKN_SDOOR); break; } } /* fall through */ case LOC_WALL: if (how == LC_MAP) return(loc_map_wall(l)); switch (l->walldoor) { case LOC_UWALL: return( (l->flags & LF_VAULT) ? SYM_UVWALL : (l->flags & LF_SHOP) ? SYM_USWALL : SYM_UWALL ); break; case LOC_HWALL: return(SYM_HWALL); break; case LOC_VWALL: return(SYM_VWALL); break; case LOC_TWALL: return(SYM_TWALL); break; default: return(SYM_UNKN_WALL); break; } break; case LOC_CAVE: switch (l->cavetype) { case LOC_STAIRS_U: return(SYM_STAIRS_U); break; case LOC_STAIRS_D: return(SYM_STAIRS_D); break; case LOC_JUSTCAVE: return(SYM_JUSTCAVE); break; default: return(SYM_UNKN_CAVE); break; } break; case LOC_GATE: switch (l->gatetype) { case LOC_GATE_IN: return(SYM_GATE_IN); break; case LOC_GATE_OUT: return(SYM_GATE_OUT); break; default: return(SYM_UNKN_GATE); break; } break; case LOC_DOOR: switch (l->walldoor) { case LOC_CHDOOR: return(SYM_CHDOOR); break; case LOC_CVDOOR: return(SYM_CVDOOR); break; case LOC_OHDOOR: return(SYM_OHDOOR); break; case LOC_OVDOOR: return(SYM_OVDOOR); break; default: return(SYM_UNKN_DOOR); break; } break; } return(SYM_UNKN_TYPE); } static void upddisp2(LOC *l, int specialp) { char c; if ( l->monst && ( (you->flags & MF_TELEPATHIC) || specialp || ( (l->flags & LF_VISIBLE) && ( !(l->monst->flags & MF_INVISIBLE) || (you->flags & MF_SEE_INVISIBLE) ) ) ) ) { c = l->monst->symbol; } else if (l->objs.inv && (specialp || (l->flags & LF_VISIBLE))) { c = objtypes[l->objs.inv->v[0]->type].sym; } else if (!specialp && !(l->flags & LF_VISIBLE)) { c = SYM_OOS; if (l->type == LOC_WALL) l->walldoor = LOC_UWALL; } else { c = loc_char(l,specialp?LC_DEBUG:LC_ORDINARY); } if (specialp) { if (l->flags & LF_VISIBLE) standout(); else standend(); if (c == SYM_OOS) c = ' '; mvaddch(l->y,l->x,c); standend(); } else { if (map && (c == SYM_OOS)) c = map_charat(map,l->x+mapox,l->y+mapoy); df[l->x][l->y] = (l->flags & LF_VISIBLE) ? 1 : 0; dc[l->x][l->y] = c; if (c != SYM_OOS) { if (l->x < min_x) min_x = l->x; if (l->x > max_x) max_x = l->x; if (l->y < min_y) min_y = l->y; if (l->y > max_y) max_y = l->y; } } } void lvdisp(LEVEL *lv) { int x; int y; LOC *l; clear(); for (x=0;xcells[x][0]; for (y=0;yon; x1 = (l->x < 1) ? 0 : l->x-1; x2 = (l->x >= LEV_X-1) ? LEV_X-1 : l->x+1; y1 = (l->y < 1) ? 0 : l->y-1; y2 = (l->y >= LEV_Y-1) ? LEV_Y-1 : l->y+1; for (x=x1;x<=x2;x++) { for (y=y1;y<=y2;y++) { upddisp1(&lv->cells[x][y]); } } } #endif void upddisp(LOC *l) { if (l->flags & LF_VISIBLE) upddisp1(l); } void upddisp1(LOC *l) { if (l->on != you->loc->on) return; upddisp2(l,0); } static int ckoos(LOC *lc) { return( (lc->type == LOC_CAVE) && (lc->cavetype == LOC_JUSTCAVE) && !(lc->flags & LF_VISIBLE) && (lc->monst == 0) ); } LOC *outofsight(LEVEL *lv) { return(randomloc(lv,&ckoos,75)); } #if 0 void checkwall(LOC *loc) { LEVEL *lv; int bits; #define NO_L 1 #define NO_U 2 #define NO_R 4 #define NO_D 8 bits = 0; if (loc->x == 0) { bits |= NO_L; } if (loc->y == 0) { bits |= NO_U; } if (loc->x >= LEV_X) { bits |= NO_R; } if (loc->y >= LEV_Y) { bits |= NO_D; } lv = loc->on; #define IF(b,from) if(!(bits&(b)))checkwall_from(loc,from) IF(NO_L|NO_U,&lv->cells[loc->x-1][loc->y-1]); IF(NO_L, &lv->cells[loc->x-1][loc->y ]); IF(NO_L|NO_D,&lv->cells[loc->x-1][loc->y+1]); IF( NO_D,&lv->cells[loc->x ][loc->y+1]); IF(NO_R|NO_D,&lv->cells[loc->x+1][loc->y+1]); IF(NO_R ,&lv->cells[loc->x+1][loc->y ]); IF(NO_R|NO_U,&lv->cells[loc->x+1][loc->y-1]); IF( NO_U,&lv->cells[loc->x ][loc->y-1]); upddisp1(loc); } #endif void checkwall_from(LOC *wall, LOC *from) { LEVEL *lv; int dx; int dy; lv = wall->on; if (lv != from->on) { panic("cells on different levels to checkwall_from"); } if ( (from->type != LOC_CAVE) && ( (from->type != LOC_DOOR) || !(from->walldoor & LOC_DOOR_OPEN) ) ) { return; } dx = from->x - wall->x; dy = from->y - wall->y; dx = (dx < 0) ? -1 : (dx > 0) ? 1 : 0; dy = (dy < 0) ? -1 : (dy > 0) ? 1 : 0; from = &lv->cells[wall->x+dx][wall->y+dy]; if (dx && dy) { LOC *h; LOC *v; LOC *c; int hiswall; int viswall; h = &lv->cells[from->x][wall->y]; v = &lv->cells[wall->x][from->y]; hiswall = ((h->type == LOC_WALL) || (h->type == LOC_SDOOR)); viswall = ((v->type == LOC_WALL) || (v->type == LOC_SDOOR)); if ((hiswall == viswall) || (h->type == LOC_DOOR) || (v->type == LOC_DOOR)) { wall->walldoor |= LOC_TWALL; return; } if (! viswall) { c = &lv->cells[wall->x-dx][wall->y]; wall->walldoor |= LOC_WALL_H; } else { c = &lv->cells[wall->x][wall->y-dy]; wall->walldoor |= LOC_WALL_V; } if ((c->type != LOC_WALL) && (c->type != LOC_SDOOR)) { wall->walldoor |= LOC_TWALL; return; } } else { LOC *a; LOC *b; wall->walldoor |= dx ? LOC_WALL_V : LOC_WALL_H; a = &lv->cells[wall->x+dy][wall->y+dx]; b = &lv->cells[wall->x-dy][wall->y-dx]; if ( ( (a->type != LOC_WALL) && (a->type != LOC_SDOOR) ) || ( (b->type != LOC_WALL) && (b->type != LOC_SDOOR) ) || (from->type == LOC_DOOR) ) { wall->walldoor |= LOC_TWALL; } } } void drawmapped(LEVEL *lv) { int x; int y; LOC *l; move(0,MXO); if (map && map_label(map)) printw("%s",map_label(map)); clrtoeol(); for (x=0;xcells[x][0]; for (y=0;y= LEV_X) || (ly >= LEV_Y)) { c = SYM_OOS; f = 0; } else { c = cv[lx][ly]; f = fv[lx][ly]; } if (c == SYM_OOS) c = ' '; if (f) standout(); mvaddch(sy,sx,c); standend(); } } } void view_map(OBJ *m) { int ox; int oy; int x; int y; int dx; int dy; int f; char c; int fulldisp; OBJ *m2; unsigned char fa[LEV_X][LEV_Y]; char ca[LEV_X][LEV_Y]; JMP j; if (setjmp(j.b)) { pop_sigint_throw(); clear(); return; } for (x=0;x': m2 = map_auto_link_dn(m,&ox,&oy); if (m2) { m = m2; fulldisp = 1; } break; case '\f': fulldisp = 1; break; case '\33': case 'q': case '\r': case '\n': clear(); return; break; } } } } int place_map(OBJ *m, int *oxp, int *oyp, const char *prompt) { int ox; int oy; int x; int y; int mx; int my; int dx; int dy; int f; char dch; char c; int fulldisp; unsigned char fa[LEV_X][LEV_Y]; char ca[LEV_X][LEV_Y]; JMP j; if (setjmp(j.b)) { pop_sigint_throw(); clear(); return(0); } fulldisp = 1; ox = ((map_maxx(m)+map_minx(m))/2) - you->loc->x; oy = ((map_maxy(m)+map_miny(m))/2) - you->loc->y; while (1) { if (fulldisp) { fulldisp = 0; clear(); if (map_label(m)) mvprintw(0,MXO,"%s",map_label(m)); mvprintw(1,MXO,"X [%d..%d]",map_minx(m),map_maxx(m)); mvprintw(2,MXO,"Y [%d..%d]",map_miny(m),map_maxy(m)); mvaddstr(LINES-1,0,prompt); } mvprintw(4,MXO,"ox=%d oy=%d",ox,oy); clrtoeol(); for (x=0;xloc->x) && (dy == you->loc->y)) { ca[x][y] = you->symbol; fa[x][y] = 1; } else { ca[x][y] = map_charat(m,mx,my); dch = ((dx >= 0) && (dy >= 0) && (dx < LEV_X) && (dy < LEV_X)) ? dc[dx][dy] : SYM_OOS; fa[x][y] = (dch != SYM_OOS) && (ca[x][y] != dch); if ((ca[x][y] == SYM_OOS) && fa[x][y]) ca[x][y] = '*'; } } } showdisp2(&fa[0],&ca[0],0,0); move(LINES-1,COLS-2); refresh(); push_sigint_throw(&j); c = getch(); pop_sigint_throw(); if (dirkey(c,&dx,&dy,0,&f,0)) { if (f & DK_CAPS) { dx *= 8; dy *= 4; } ox += dx; oy += dy; } else { switch (c) { case '\f': fulldisp = 1; break; case '\33': case 'q': clear(); return(0); break; case '\r': case '\n': *oxp = ox; *oyp = oy; clear(); return(1); break; } } } } void showdisp(void) { if (min_x <= max_x) { if (min_x+dispox < 0) dispox = - min_x; if (min_y+dispoy < 0) dispoy = - min_y; if (max_x+dispox >= LEV_X) dispox = LEV_X-1 - max_x; if (max_y+dispoy >= LEV_Y) dispoy = LEV_Y-1 - max_y; } showdisp2(&df[0],&dc[0],dispox,dispoy); } void cleardisp(void) { int x; int y; for (x=0;x= LINES-1) { clr = 1; clear(); for (i=0;i maxl) maxl = i; } for (n=0;n (1) { f = fopenmalloc(&s); linestat = (*line)(f); fclose(f); switch (linestat) { case DL_L_MORE: break; case DL_L_DONE: free(s); break <"lines">; } l = strlen(s); if (l > COLS-6) { char *s2; sp = s; while (l > COLS-2) { s2 = malloc(1+COLS-2); bcopy(sp,s2,COLS-2); s2[COLS-2] = '\0'; nexttxt(s2); sp += COLS-2; l -= COLS-2; } nexttxt(strdup(sp)); free(s); s = 0; } else { sp = s; s = 0; nexttxt(sp); } } s = 0; if (n) { if (clr) { int i; for (i=0;i LEV_X) { int i; for (i=0;i 1) { int i; for (i=0;i LEV_Y) clr = 1; } else if (n == 1) { mvprintw(0,0,"%s ",txt[0]); } getch_loop(""); if (clr) clear(); } retnow:; for (n=0;n