/** * Save a simple text screendump. */ static void do_cmd_save_screen_text(void) { int y, x; int a = 0; wchar_t c = L' '; ang_file *fff; char buf[1024]; char *p; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt"); fff = file_open(buf, MODE_WRITE, FTYPE_TEXT); if (!fff) return; /* Save screen */ screen_save(); /* Dump the screen */ for (y = 0; y < 24; y++) { p = buf; /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Terminate */ *p = '\0'; /* End the row */ file_putf(fff, "%s\n", buf); } /* Skip a line */ file_putf(fff, "\n"); /* Dump the screen */ for (y = 0; y < 24; y++) { /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = hack[a & 0x0F]; } /* Terminate */ buf[x] = '\0'; /* End the row */ file_putf(fff, "%s\n", buf); } /* Skip a line */ file_putf(fff, "\n"); /* Close it */ file_close(fff); /* Message */ msg("Screen dump saved."); event_signal(EVENT_MESSAGE_FLUSH); /* Load screen */ screen_load(); }
/** * Draw a visible path over the squares between (x1,y1) and (x2,y2). * * The path consists of "*", which are white except where there is a * monster, object or feature in the grid. * * This routine has (at least) three weaknesses: * - remembered objects/walls which are no longer present are not shown, * - squares which (e.g.) the player has walked through in the dark are * treated as unknown space. * - walls which appear strange due to hallucination aren't treated correctly. * * The first two result from information being lost from the dungeon arrays, * which requires changes elsewhere */ static int draw_path(u16b path_n, u16b *path_g, wchar_t *c, int *a, int y1, int x1) { int i; bool on_screen; /* No path, so do nothing. */ if (path_n < 1) return 0; /* The starting square is never drawn, but notice if it is being * displayed. In theory, it could be the last such square. */ on_screen = panel_contains(y1, x1); /* Draw the path. */ for (i = 0; i < path_n; i++) { byte colour; /* Find the co-ordinates on the level. */ int y = GRID_Y(path_g[i]); int x = GRID_X(path_g[i]); /* * As path[] is a straight line and the screen is oblong, * there is only section of path[] on-screen. * If the square being drawn is visible, this is part of it. * If none of it has been drawn, continue until some of it * is found or the last square is reached. * If some of it has been drawn, finish now as there are no * more visible squares to draw. */ if (panel_contains(y,x)) on_screen = TRUE; else if (on_screen) break; else continue; /* Find the position on-screen */ move_cursor_relative(y,x); /* This square is being overwritten, so save the original. */ Term_what(Term->scr->cx, Term->scr->cy, a+i, c+i); /* Choose a colour. */ if (cave->m_idx[y][x] && cave_monster_at(cave, y, x)->ml) { /* Visible monsters are red. */ monster_type *m_ptr = cave_monster_at(cave, y, x); /* Mimics act as objects */ if (rf_has(m_ptr->race->flags, RF_UNAWARE)) colour = TERM_YELLOW; else colour = TERM_L_RED; } else if (cave->o_idx[y][x] && object_byid(cave->o_idx[y][x])->marked) /* Known objects are yellow. */ colour = TERM_YELLOW; else if (!cave_ispassable(cave, y,x) && ((cave->info[y][x] & (CAVE_MARK)) || player_can_see_bold(y,x))) /* Known walls are blue. */ colour = TERM_BLUE; else if (!(cave->info[y][x] & (CAVE_MARK)) && !player_can_see_bold(y,x)) /* Unknown squares are grey. */ colour = TERM_L_DARK; else /* Unoccupied squares are white. */ colour = TERM_WHITE; /* Draw the path segment */ (void)Term_addch(colour, L'*'); } return i; }
/** * Hack -- load a screen dump from a file * * ToDo: Add support for loading/saving screen-dumps with graphics * and pseudo-graphics. Allow the player to specify the filename * of the dump. */ void do_cmd_load_screen(void) { int i, y, x; int a = 0; wchar_t c = L' '; bool okay = TRUE; ang_file *fp; char buf[1024]; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt"); fp = file_open(buf, MODE_READ, FTYPE_TEXT); if (!fp) return; /* Save screen */ screen_save(); /* Clear the screen */ Term_clear(); /* Load the screen */ for (y = 0; okay && (y < 24); y++) { /* Get a line of data */ if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE; /* Show each row */ for (x = 0; x < 79; x++) { text_mbstowcs(&c, &buf[x], 1); /* Put the attr/char */ Term_draw(x, y, COLOUR_WHITE, c); } } /* Get the blank line */ if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE; /* Dump the screen */ for (y = 0; okay && (y < 24); y++) { /* Get a line of data */ if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE; /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Look up the attr */ for (i = 0; i < BASIC_COLORS; i++) /* Use attr matches */ if (hack[i] == buf[x]) a = i; /* Put the attr/char */ Term_draw(x, y, a, c); } } /* Close it */ file_close(fp); /* Message */ msg("Screen dump loaded."); event_signal(EVENT_MESSAGE_FLUSH); /* Load screen */ screen_load(); }
/** * Draw a visible path over the squares between (x1,y1) and (x2,y2). * * The path consists of "*", which are white except where there is a * monster, object or feature in the grid. * * This routine has (at least) three weaknesses: * - remembered objects/walls which are no longer present are not shown, * - squares which (e.g.) the player has walked through in the dark are * treated as unknown space. * - walls which appear strange due to hallucination aren't treated correctly. * * The first two result from information being lost from the dungeon arrays, * which requires changes elsewhere */ static int draw_path(u16b path_n, struct loc *path_g, wchar_t *c, int *a, int y1, int x1) { int i; bool on_screen; /* No path, so do nothing. */ if (path_n < 1) return 0; /* The starting square is never drawn, but notice if it is being * displayed. In theory, it could be the last such square. */ on_screen = panel_contains(y1, x1); /* Draw the path. */ for (i = 0; i < path_n; i++) { byte colour; /* Find the co-ordinates on the level. */ int y = path_g[i].y; int x = path_g[i].x; struct monster *mon = square_monster(cave, y, x); struct object *obj = square_object(cave, y, x); /* * As path[] is a straight line and the screen is oblong, * there is only section of path[] on-screen. * If the square being drawn is visible, this is part of it. * If none of it has been drawn, continue until some of it * is found or the last square is reached. * If some of it has been drawn, finish now as there are no * more visible squares to draw. */ if (panel_contains(y,x)) on_screen = TRUE; else if (on_screen) break; else continue; /* Find the position on-screen */ move_cursor_relative(y,x); /* This square is being overwritten, so save the original. */ Term_what(Term->scr->cx, Term->scr->cy, a+i, c+i); /* Choose a colour. */ if (mon && mflag_has(mon->mflag, MFLAG_VISIBLE)) { /* Mimics act as objects */ if (rf_has(mon->race->flags, RF_UNAWARE)) colour = COLOUR_YELLOW; else /* Visible monsters are red. */ colour = COLOUR_L_RED; } else if (obj && obj->marked) /* Known objects are yellow. */ colour = COLOUR_YELLOW; else if ((!square_isprojectable(cave, y,x) && square_ismark(cave, y, x)) || square_isseen(cave, y, x)) /* Known walls are blue. */ colour = COLOUR_BLUE; else if (!square_ismark(cave, y, x) && !square_isseen(cave, y, x)) /* Unknown squares are grey. */ colour = COLOUR_L_DARK; else /* Unoccupied squares are white. */ colour = COLOUR_WHITE; /* Draw the path segment */ (void)Term_addch(colour, L'*'); } return i; }
/* * Make screen dump to buffer */ cptr make_screen_dump(void) { BUF *screen_buf; int y, x, i; cptr ret; byte a = 0, old_a = 0; char c = ' '; static cptr html_head[] = { "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n", "<pre>", 0, }; static cptr html_foot[] = { "</pre>\n", "</body>\n</html>\n", 0, }; bool old_use_graphics = use_graphics; int wid, hgt; Term_get_size(&wid, &hgt); /* Alloc buffer */ screen_buf = buf_new(); if (screen_buf == NULL) return (NULL); if (old_use_graphics) { /* Clear -more- prompt first */ msg_print(NULL); use_graphics = FALSE; reset_visuals(); /* Redraw everything */ p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY); /* Hack -- update */ handle_stuff(); } for (i = 0; html_head[i]; i++) buf_sprintf(screen_buf, html_head[i]); /* Dump the screen */ for (y = 0; y < hgt; y++) { /* Start the row */ if (y != 0) buf_sprintf(screen_buf, "\n"); /* Dump each row */ for (x = 0; x < wid - 1; x++) { int rv, gv, bv; cptr cc = NULL; /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); switch (c) { case '&': cc = "&"; break; case '<': cc = "<"; break; case '>': cc = ">"; break; #ifdef WINDOWS case 0x1f: c = '.'; break; case 0x7f: c = (a == 0x09) ? '%' : '#'; break; #endif } a = a & 0x0F; if ((y == 0 && x == 0) || a != old_a) { rv = angband_color_table[a][1]; gv = angband_color_table[a][2]; bv = angband_color_table[a][3]; buf_sprintf(screen_buf, "%s<font color=\"#%02x%02x%02x\">", ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv); old_a = a; } if (cc) buf_sprintf(screen_buf, "%s", cc); else buf_sprintf(screen_buf, "%c", c); } } buf_sprintf(screen_buf, "</font>"); for (i = 0; html_foot[i]; i++) buf_sprintf(screen_buf, html_foot[i]); /* Screen dump size is too big ? */ if (screen_buf->size + 1> SCREEN_BUF_SIZE) { ret = NULL; } else { /* Terminate string */ buf_append(screen_buf, "", 1); ret = string_make(screen_buf->data); } /* Free buffer */ buf_delete(screen_buf); if (old_use_graphics) { use_graphics = TRUE; reset_visuals(); /* Redraw everything */ p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY); /* Hack -- update */ handle_stuff(); } return ret; }
/* * Print some (colored) text to the screen at the current cursor position, * automatically "wrapping" existing text (at spaces) when necessary to * avoid placing any text into the last column, and clearing every line * before placing any text in that line. Also, allow "newline" to force * a "wrap" to the next line. Advance the cursor as needed so sequential * calls to this function will work correctly. * * Once this function has been called, the cursor should not be moved * until all the related "text_out()" calls to the window are complete. * * This function will correctly handle any width up to the maximum legal * value of 256, though it works best for a standard 80 character width. */ void text_out_to_screen(byte a, const char *str) { int x, y; int wid, h; int wrap; const wchar_t *s; wchar_t buf[1024]; /* Obtain the size */ (void)Term_get_size(&wid, &h); /* Obtain the cursor */ (void)Term_locate(&x, &y); /* Copy to a rewriteable string */ Term_mbstowcs(buf, str, 1024); /* Use special wrapping boundary? */ if ((text_out_wrap > 0) && (text_out_wrap < wid)) wrap = text_out_wrap; else wrap = wid; /* Process the string */ for (s = buf; *s; s++) { wchar_t ch; /* Force wrap */ if (*s == L'\n') { /* Wrap */ x = text_out_indent; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); x += text_out_pad; Term_gotoxy(x, y); continue; } /* Clean up the char */ ch = (iswprint(*s) ? *s : L' '); /* Wrap words as needed */ if ((x >= wrap - 1) && (ch != L' ')) { int i, n = 0; byte av[256]; wchar_t cv[256]; /* Wrap word */ if (x < wrap) { /* Scan existing text */ for (i = wrap - 2; i >= 0; i--) { /* Grab existing attr/char */ Term_what(i, y, &av[i], &cv[i]); /* Break on space */ if (cv[i] == L' ') break; /* Track current word */ n = i; } } /* Special case */ if (n == 0) n = wrap; /* Clear line */ Term_erase(n, y, 255); /* Wrap */ x = text_out_indent; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); x += text_out_pad; Term_gotoxy(x, y); /* Wrap the word (if any) */ for (i = n; i < wrap - 1; i++) { /* Dump */ Term_addch(av[i], cv[i]); /* Advance (no wrap) */ if (++x > wrap) x = wrap; } } /* Dump */ Term_addch(a, ch); /* Advance */ if (++x > wrap) x = wrap; } }
/* * Hack -- save a screen dump to a file */ void do_cmd_save_screen(void) { /* Do we use a special screendump function ? */ if (screendump_aux) { /* Dump the screen to a graphics file */ (*screendump_aux)(); } /* Dump the screen as text */ else { s32b y, x; s32b wid, hgt; byte a = 0; char c = ' '; PHYSFS_file *fff; char buf[1024]; /* Build the filename */ path_build(buf, 1024, TENGINE_DIR_USER, "dump.txt"); /* Append to the file */ fff = my_fopen(buf, "w"); /* Oops */ if (!fff) return; /* Retrieve the current screen size */ Term_get_size(&wid, &hgt); /* Enter "icky" mode */ character_icky++; /* Save the screen */ Term_save(); /* Dump the screen */ for (y = 0; y < hgt; y++) { /* Dump each row */ for (x = 0; x < wid; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = c; } /* Terminate */ buf[x] = '\0'; /* End the row */ fprintf(fff, "%s\n", buf); } /* Skip a line */ fprintf(fff, "\n"); /* Dump the screen */ for (y = 0; y < hgt; y++) { /* Dump each row */ for (x = 0; x < wid; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = hack[a & 0x0F]; } /* Terminate */ buf[x] = '\0'; /* End the row */ fprintf(fff, "%s\n", buf); } /* Skip a line */ fprintf(fff, "\n"); /* Close it */ my_fclose(fff); /* Message */ msg_print("Screen dump saved."); msg_print(NULL); /* Restore the screen */ Term_load(); /* Leave "icky" mode */ character_icky--; } }
/* * Hack -- load a screen dump from a file * * ToDo: Add support for loading/saving screen-dumps with graphics * and pseudo-graphics. Allow the player to specify the filename * of the dump. */ void do_cmd_load_screen(void) { int i, y, x; byte a = 0; char c = ' '; bool okay = TRUE; ang_file *fp; char buf[1024]; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt"); fp = file_open(buf, MODE_READ, -1); if (!fp) return; /* Save screen */ screen_save(); /* Clear the screen */ Term_clear(); /* Load the screen */ for (y = 0; okay && (y < 24); y++) { /* Get a line of data */ if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE; /* Show each row */ for (x = 0; x < 79; x++) { /* Put the attr/char */ Term_draw(x, y, TERM_WHITE, buf[x]); } } /* Get the blank line */ if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE; /* Dump the screen */ for (y = 0; okay && (y < 24); y++) { /* Get a line of data */ if (!file_getl(fp, buf, sizeof(buf))) okay = FALSE; /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Look up the attr */ for (i = 0; i < BASIC_COLORS; i++) { /* Use attr matches */ if (hack[i] == buf[x]) a = i; } /* Put the attr/char */ Term_draw(x, y, a, c); } } /* Close it */ file_close(fp); /* Message */ msg("Screen dump loaded."); message_flush(); /* Load screen */ screen_load(); }
/* * Save a simple text screendump. */ static void do_cmd_save_screen_text(void) { int y, x; byte a = 0; char c = ' '; ang_file *fff; char buf[1024]; /* Build the filename */ path_build(buf, 1024, ANGBAND_DIR_USER, "dump.txt"); fff = file_open(buf, MODE_WRITE, FTYPE_TEXT); if (!fff) return; /* Save screen */ screen_save(); /* Dump the screen */ for (y = 0; y < 24; y++) { /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = c; } /* Terminate */ buf[x] = '\0'; /* End the row */ file_putf(fff, "%s\n", buf); } /* Skip a line */ file_putf(fff, "\n"); /* Dump the screen */ for (y = 0; y < 24; y++) { /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = hack[a & 0x0F]; } /* Terminate */ buf[x] = '\0'; /* End the row */ file_putf(fff, "%s\n", buf); } /* Skip a line */ file_putf(fff, "\n"); /* Close it */ file_close(fff); /* Message */ msg("Screen dump saved."); message_flush(); /* Load screen */ screen_load(); }
/* * Create a spoiler file for monsters (-SHAWN-) */ static void spoil_mon_info(void) { int n, x, y; bool breath, magic; u32b flags1, flags2, flags3, flags4, flags5, flags6; const bool old_spoil_mon = spoil_mon; byte a; char c, c2; byte old_moncol[MAX_MONCOL]; /* Give full information. */ spoil_mon = TRUE; for (n = 0; n < MAX_MONCOL; n++) old_moncol[n] = moncol[n].gfx.xa; /* Hack - hide some information. */ moncol[0].gfx.xa = moncol[8].gfx.xa = moncol[18].gfx.xa = TERM_DARK; /* Dump the header */ spoil_out("Monster Spoilers for %s Version %s\n", GAME_NAME, GAME_VERSION); spoil_out("------------------------------------------\n\n"); /* * List all monsters in order (except the ghost). */ for (n = 1; n < MAX_R_IDX; n++) { monster_race *r_ptr = &r_info[n]; /* Skip "fake" monsters. */ if (is_fake_monster(r_ptr)) continue; /* Extract the flags */ flags1 = r_ptr->flags1; flags2 = r_ptr->flags2; flags3 = r_ptr->flags3; flags4 = r_ptr->flags4; flags5 = r_ptr->flags5; flags6 = r_ptr->flags6; breath = FALSE; magic = FALSE; /* Prefix */ if (flags1 & (RF1_GUARDIAN)) { spoil_out("[G] "); } else if (flags1 & (RF1_UNIQUE)) { spoil_out("[U] "); } else { spoil_out("The "); } /* Name */ spoil_out("%v (", monster_desc_aux_f3, r_ptr, 1, 0); /* Color */ spoil_out(attr_to_text(r_ptr->gfx.da)); /* Symbol --(-- */ spoil_out(" '%c')\n", r_ptr->gfx.dc); /* Indent */ spoil_out("=== "); /* Number */ spoil_out("Num:%d ", n); /* Level */ spoil_out("Lev:%d ", r_ptr->level); /* Rarity */ spoil_out("Rar:%d ", r_ptr->rarity); /* Speed */ spoil_out("Spd:%+d ", (r_ptr->speed - 110)); /* Hitpoints */ if ((flags1 & (RF1_FORCE_MAXHP)) || (r_ptr->hside == 1)) { spoil_out("Hp:%d ", r_ptr->hdice * r_ptr->hside); } else { spoil_out("Hp:%dd%d ", r_ptr->hdice, r_ptr->hside); } /* Armor Class */ spoil_out("Ac:%d ", r_ptr->ac); /* Power */ spoil_out("Power:%ld\n", (long)(r_ptr->mexp)); /* Clear the screen before every monster. */ Term_clear(); /* Display the monster on screen. */ screen_roff(n); /* Dump the on-screen display (excluding the title). */ for (c2 = 0, y = 1; y < Term->hgt; y++) { for (x = 0; x < Term->wid; x++) { /* Check the character. */ Term_what(x, y, &a, &c); /* Ignore blanked text. */ if (a == TERM_DARK) continue; /* Ignore repeated spaces. */ if (c == ' ' && c2 == ' ') continue; /* Dump the character. */ spoil_out("%c", c); /* Remember the character. */ c2 = c; } /* Put a space at the end of every line. */ if (c2 != ' ') spoil_out(" "); } spoil_out(NULL); } /* Restore spoil_mon. */ spoil_mon = old_spoil_mon; /* Restore moncol[]. */ for (n = 0; n < MAX_MONCOL; n++) moncol[n].gfx.xa = old_moncol[n]; /* Don't leave a monster display lying around. */ Term_clear(); }
/* * Hack -- Dump a character description file * * XXX XXX XXX Allow the "full" flag to dump additional info, * and trigger its usage from various places in the code. */ errr file_character(const char *path, bool full) { int i, x, y; int a; wchar_t c; ang_file *fp; struct store *st_ptr = &stores[STORE_HOME]; char o_name[80]; char buf[1024]; char *p; /* Unused parameter */ (void)full; /* Open the file for writing */ fp = file_open(path, MODE_WRITE, FTYPE_TEXT); if (!fp) return (-1); /* Begin dump */ file_putf(fp, " [%s Character Dump]\n\n", buildid); /* Display player */ display_player(0); /* Dump part of the screen */ for (y = 1; y < 23; y++) { p = buf; /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Back up over spaces */ while ((p > buf) && (p[-1] == ' ')) --p; /* Terminate */ *p = '\0'; /* End the row */ x_file_putf(fp, "%s\n", buf); } /* Skip a line */ file_putf(fp, "\n"); /* Display player */ display_player(1); /* Dump part of the screen */ for (y = 11; y < 20; y++) { p = buf; /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Back up over spaces */ while ((p > buf) && (p[-1] == ' ')) --p; /* Terminate */ *p = '\0'; /* End the row */ x_file_putf(fp, "%s\n", buf); } /* Skip a line */ file_putf(fp, "\n"); /* Dump part of the screen */ for (y = 11; y < 20; y++) { p = buf; /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x + 40, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Back up over spaces */ while ((p > buf) && (p[-1] == ' ')) --p; /* Terminate */ *p = '\0'; /* End the row */ x_file_putf(fp, "%s\n", buf); } /* Skip some lines */ file_putf(fp, "\n\n"); /* If dead, dump last messages -- Prfnoff */ if (p_ptr->is_dead) { i = messages_num(); if (i > 15) i = 15; file_putf(fp, " [Last Messages]\n\n"); while (i-- > 0) { x_file_putf(fp, "> %s\n", message_str((s16b)i)); } x_file_putf(fp, "\nKilled by %s.\n\n", p_ptr->died_from); } /* Dump the equipment */ file_putf(fp, " [Character Equipment]\n\n"); for (i = INVEN_WIELD; i < ALL_INVEN_TOTAL; i++) { if (i == INVEN_TOTAL) { file_putf(fp, "\n\n [Character Quiver]\n\n"); continue; } object_desc(o_name, sizeof(o_name), &p_ptr->inventory[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, "%c) %s\n", index_to_label(i), o_name); if (p_ptr->inventory[i].kind) object_info_chardump(fp, &p_ptr->inventory[i], 5, 72); } /* Dump the inventory */ file_putf(fp, "\n\n [Character Inventory]\n\n"); for (i = 0; i < INVEN_PACK; i++) { if (!p_ptr->inventory[i].kind) break; object_desc(o_name, sizeof(o_name), &p_ptr->inventory[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, "%c) %s\n", index_to_label(i), o_name); object_info_chardump(fp, &p_ptr->inventory[i], 5, 72); } file_putf(fp, "\n\n"); /* Dump the Home -- if anything there */ if (st_ptr->stock_num) { /* Header */ file_putf(fp, " [Home Inventory]\n\n"); /* Dump all available items */ for (i = 0; i < st_ptr->stock_num; i++) { object_desc(o_name, sizeof(o_name), &st_ptr->stock[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, "%c) %s\n", I2A(i), o_name); object_info_chardump(fp, &st_ptr->stock[i], 5, 72); } /* Add an empty line */ file_putf(fp, "\n\n"); } /* Dump character history */ dump_history(fp); file_putf(fp, "\n\n"); /* Dump options */ file_putf(fp, " [Options]\n\n"); /* Dump options */ for (i = 0; i < OPT_PAGE_MAX - 1; i++) { int j; const char *title = ""; switch (i) { case 0: title = "Interface"; break; case 1: title = "Warning"; break; case 2: title = "Birth"; break; } file_putf(fp, " [%s]\n\n", title); for (j = 0; j < OPT_PAGE_PER; j++) { int opt = option_page[i][j]; if (!option_name(opt)) continue; file_putf(fp, "%-45s: %s (%s)\n", option_desc(opt), op_ptr->opt[opt] ? "yes" : "no ", option_name(opt)); } /* Skip some lines */ file_putf(fp, "\n"); } file_close(fp); /* Success */ return (0); }
/** * Display a "tomb-stone" */ static void print_tomb(void) { cptr p; int offset = 12; char tmp[160]; char buf[1024]; ang_file *fp; #ifdef _WIN32_WCE time_t ct = fake_time((time_t) 0); #else time_t ct = time((time_t) 0); #endif bool boat = ((p_ptr->total_winner) && (player_has(PF_ELVEN))); bool tree = ((p_ptr->total_winner) && (player_has(PF_WOODEN) || player_has(PF_DIVINE))); /* Clear screen */ Term_clear(); /* Build the filename */ if (tree) path_build(buf, 1024, ANGBAND_DIR_FILE, "tree.txt"); else if (boat) path_build(buf, 1024, ANGBAND_DIR_FILE, "boat.txt"); else path_build(buf, 1024, ANGBAND_DIR_FILE, "dead.txt"); /* Open the News file */ fp = file_open(buf, MODE_READ, FTYPE_TEXT); /* Dump */ if (fp) { int i, y, x; byte a = 0; char c = ' '; bool okay = TRUE; int len; /* Load the screen */ for (y = 0; okay; y++) { /* Get a line of data */ if (!file_getl(fp, buf, 1024)) okay = FALSE; /* Stop on blank line */ if (!buf[0]) break; /* Get the width */ len = strlen(buf); /* XXX Restrict to current screen size */ if (len >= Term->wid) len = Term->wid; /* Show each row */ for (x = 0; x < len; x++) { /* Put the attr/char */ Term_draw(x, y, TERM_WHITE, buf[x]); } } /* Get the blank line */ /* if (my_fgets(fp, buf, 1024)) okay = FALSE; */ /* Load the screen */ for (y = 0; okay; y++) { /* Get a line of data */ if (!file_getl(fp, buf, 1024)) okay = FALSE; /* Stop on blank line */ if (!buf[0]) break; /* Get the width */ len = strlen(buf); /* XXX Restrict to current screen size */ if (len >= Term->wid) len = Term->wid; /* Show each row */ for (x = 0; x < len; x++) { /* Get the attr/char */ (void) (Term_what(x, y, &a, &c)); /* Look up the attr */ for (i = 0; i < 16; i++) { /* Use attr matches */ if (hack[i] == buf[x]) a = i; } /* Put the attr/char */ Term_draw(x, y, a, c); } /* Place the cursor */ Term_gotoxy(x, y); } /* Get the blank line */ /* if (my_fgets(fp, buf, 1024)) okay = FALSE; */ /* Close it */ file_close(fp); } /* King or Queen */ if (p_ptr->total_winner || (p_ptr->lev > PY_MAX_LEVEL)) { p = "Magnificent"; } /* Normal */ else { p = cp_ptr->title[(p_ptr->lev - 1) / 5]; } /* Set offset */ offset = 11; center_string(buf, op_ptr->full_name); put_str(buf, 6, offset); center_string(buf, "the"); put_str(buf, 7, offset); center_string(buf, p); put_str(buf, 8, offset); center_string(buf, cp_ptr->name); put_str(buf, 10, offset); sprintf(tmp, "Level: %d", (int) p_ptr->lev); center_string(buf, tmp); put_str(buf, 11, offset); sprintf(tmp, "Exp: %ld", (long) p_ptr->exp); center_string(buf, tmp); put_str(buf, 12, offset); sprintf(tmp, "AU: %ld", (long) p_ptr->au); center_string(buf, tmp); put_str(buf, 13, offset); if (p_ptr->depth) sprintf(tmp, "Killed in %s level %d", locality_name[stage_map[p_ptr->stage][LOCALITY]], p_ptr->depth); else if (boat) sprintf(tmp, "Sailed victorious to Aman."); else if (tree) sprintf(tmp, "Retired to Fangorn Forest."); else sprintf(tmp, "Killed in %s town", locality_name[stage_map[p_ptr->stage][LOCALITY]]); center_string(buf, tmp); put_str(buf, 14, offset); if (!(boat || tree)) { sprintf(tmp, "by %s.", p_ptr->died_from); center_string(buf, tmp); put_str(buf, 15, offset); } #ifdef _WIN32_WCE { char *fake_ctime(const unsigned long *fake_time_t); sprintf(tmp, "%-.24s", fake_ctime(&ct)); } #else sprintf(tmp, "%-.24s", ctime(&ct)); #endif center_string(buf, tmp); put_str(buf, 17, offset); }
/* Take an html screenshot */ void html_screenshot(const char *name, int mode) { int y, x; int wid, hgt; byte a = TERM_WHITE; byte oa = TERM_WHITE; char c = ' '; const char *new_color_fmt = (mode == 0) ? "<font color=\"#%02X%02X%02X\">" : "[COLOR=\"#%02X%02X%02X\"]"; const char *change_color_fmt = (mode == 0) ? "</font><font color=\"#%02X%02X%02X\">" : "[/COLOR][COLOR=\"#%02X%02X%02X\"]"; const char *close_color_fmt = mode == 0 ? "</font>" : "[/COLOR]"; ang_file *fp; char buf[1024]; path_build(buf, sizeof(buf), ANGBAND_DIR_USER, name); fp = file_open(buf, MODE_WRITE, FTYPE_TEXT); /* Oops */ if (!fp) { plog_fmt("Cannot write the '%s' file!", buf); return; } /* Retrieve current screen size */ Term_get_size(&wid, &hgt); if (mode == 0) { file_putf(fp, "<!DOCTYPE html><html><head>\n"); file_putf(fp, " <meta='generator' content='%s'>\n", buildid); file_putf(fp, " <title>%s</title>\n", name); file_putf(fp, "</head>\n\n"); file_putf(fp, "<body style='color: #fff; background: #000;'>\n"); file_putf(fp, "<pre>\n"); } else { file_putf(fp, "[CODE][TT][BC=black][COLOR=white]\n"); } /* Dump the screen */ for (y = 0; y < hgt; y++) { for (x = 0; x < wid; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Color change */ if (oa != a && c != ' ') { /* From the default white to another color */ if (oa == TERM_WHITE) { file_putf(fp, new_color_fmt, angband_color_table[a][1], angband_color_table[a][2], angband_color_table[a][3]); } /* From another color to the default white */ else if (a == TERM_WHITE) { file_putf(fp, close_color_fmt); } /* Change colors */ else { file_putf(fp, change_color_fmt, angband_color_table[a][1], angband_color_table[a][2], angband_color_table[a][3]); } /* Remember the last color */ oa = a; } /* Write the character and escape special HTML characters */ if (mode == 0) write_html_escape_char(fp, c); else file_putf(fp, "%c", c); } /* End the row */ file_putf(fp, "\n"); } /* Close the last font-color tag if necessary */ if (oa != TERM_WHITE) file_putf(fp, close_color_fmt); if (mode == 0) { file_putf(fp, "</pre>\n"); file_putf(fp, "</body>\n"); file_putf(fp, "</html>\n"); } else { file_putf(fp, "[/COLOR][/BC][/TT][/CODE]\n"); } /* Close it */ file_close(fp); }
/* * Hack -- Dump a character description file * * XXX XXX XXX Allow the "full" flag to dump additional info, * and trigger its usage from various places in the code. */ errr file_character(const char *path, bool full) { int i, x, y; byte a; char c; ang_file *fp; struct store *st_ptr = &stores[STORE_HOME]; char o_name[80]; byte (*old_xchar_hook)(byte c) = Term.xchar_hook; char buf[1024]; /* We use either ascii or system-specific encoding */ int encoding = OPT(xchars_to_file) ? SYSTEM_SPECIFIC : ASCII; /* Unused parameter */ (void)full; /* Open the file for writing */ fp = file_open(path, MODE_WRITE, FTYPE_TEXT); if (!fp) return (-1); /* Display the requested encoding -- ASCII or system-specific */ if (!OPT(xchars_to_file)) Term.xchar_hook = null; /* Begin dump */ file_putf(fp, " [%s Character Dump]\n\n", buildid); /* Display player */ display_player(0); /* Dump part of the screen */ for (y = 1; y < 23; y++) { /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = c; } /* Back up over spaces */ while ((x > 0) && (buf[x-1] == ' ')) --x; /* Terminate */ buf[x] = '\0'; /* End the row */ x_file_putf(fp, encoding, "%s\n", buf); } /* Skip a line */ file_putf(fp, "\n"); /* Display player */ display_player(1); /* Dump part of the screen */ for (y = 11; y < 20; y++) { /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ buf[x] = c; } /* Back up over spaces */ while ((x > 0) && (buf[x-1] == ' ')) --x; /* Terminate */ buf[x] = '\0'; /* End the row */ x_file_putf(fp, encoding, "%s\n", buf); } /* Skip a line */ file_putf(fp, "\n"); /* Dump part of the screen */ for (y = 11; y < 20; y++) { /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x + 40, y, &a, &c)); /* Dump it */ buf[x] = c; } /* Back up over spaces */ while ((x > 0) && (buf[x-1] == ' ')) --x; /* Terminate */ buf[x] = '\0'; /* End the row */ x_file_putf(fp, encoding, "%s\n", buf); } /* Skip some lines */ file_putf(fp, "\n\n"); /* If dead, dump last messages -- Prfnoff */ if (p_ptr.is_dead) { i = messages_num(); if (i > 15) i = 15; file_putf(fp, " [Last Messages]\n\n"); while (i-- > 0) { x_file_putf(fp, encoding, "> %s\n", message_str((s16b)i)); } x_file_putf(fp, encoding, "\nKilled by %s.\n\n", p_ptr.died_from); } /* Dump the equipment */ file_putf(fp, " [Character Equipment]\n\n"); for (i = INVEN_WIELD; i < ALL_INVEN_TOTAL; i++) { if (i == INVEN_TOTAL) { file_putf(fp, "\n\n [Character Quiver]\n\n"); continue; } object_desc(o_name, sizeof(o_name), &p_ptr.inventory[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, encoding, "%c) %s\n", index_to_label(i), o_name); if (p_ptr.inventory[i].kind) object_info_chardump(fp, &p_ptr.inventory[i], 5, 72); } /* Dump the inventory */ file_putf(fp, "\n\n [Character Inventory]\n\n"); for (i = 0; i < INVEN_PACK; i++) { if (!p_ptr.inventory[i].kind) break; object_desc(o_name, sizeof(o_name), &p_ptr.inventory[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, encoding, "%c) %s\n", index_to_label(i), o_name); object_info_chardump(fp, &p_ptr.inventory[i], 5, 72); } file_putf(fp, "\n\n"); /* Dump the Home -- if anything there */ if (st_ptr.stock_num) { /* Header */ file_putf(fp, " [Home Inventory]\n\n"); /* Dump all available items */ for (i = 0; i < st_ptr.stock_num; i++) { object_desc(o_name, sizeof(o_name), &st_ptr.stock[i], ODESC_PREFIX | ODESC_FULL); x_file_putf(fp, encoding, "%c) %s\n", I2A(i), o_name); object_info_chardump(fp, &st_ptr.stock[i], 5, 72); } /* Add an empty line */ file_putf(fp, "\n\n"); } /* Dump character history */ dump_history(fp); file_putf(fp, "\n\n"); /* Dump options */ file_putf(fp, " [Options]\n\n"); /* Dump options */ for (i = OPT_BIRTH; i < OPT_BIRTH + N_OPTS_BIRTH; i++) { if (option_name(i)) { file_putf(fp, "%-45s: %s (%s)\n", option_desc(i), op_ptr.opt[i] ? "yes" : "no ", option_name(i)); } } /* Skip some lines */ file_putf(fp, "\n\n"); /* Return to standard display */ Term.xchar_hook = old_xchar_hook; file_close(fp); /* Success */ return (0); }
/** * Take an html screenshot */ void html_screenshot(const char *path, int mode) { int y, x; int wid, hgt; int a = COLOUR_WHITE; int oa = COLOUR_WHITE; int fg_colour = COLOUR_WHITE; int bg_colour = COLOUR_DARK; wchar_t c = L' '; const char *new_color_fmt = (mode == 0) ? "<font color=\"#%02X%02X%02X\" style=\"background-color: #%02X%02X%02X\">" : "[COLOR=\"#%02X%02X%02X\"]"; const char *change_color_fmt = (mode == 0) ? "</font><font color=\"#%02X%02X%02X\" style=\"background-color: #%02X%02X%02X\">" : "[/COLOR][COLOR=\"#%02X%02X%02X\"]"; const char *close_color_fmt = mode == 0 ? "</font>" : "[/COLOR]"; ang_file *fp; fp = file_open(path, MODE_WRITE, FTYPE_TEXT); /* Oops */ if (!fp) { plog_fmt("Cannot write the '%s' file!", path); return; } /* Retrieve current screen size */ Term_get_size(&wid, &hgt); if (mode == 0) { file_putf(fp, "<!DOCTYPE html><html><head>\n"); file_putf(fp, " <meta='generator' content='%s'>\n", buildid); file_putf(fp, " <title>%s</title>\n", path); file_putf(fp, "</head>\n\n"); file_putf(fp, "<body style='color: #fff; background: #000;'>\n"); file_putf(fp, "<pre>\n"); } else { file_putf(fp, "[CODE][TT][BC=black][COLOR=white]\n"); } /* Dump the screen */ for (y = 0; y < hgt; y++) { for (x = 0; x < wid; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Set the foreground and background */ fg_colour = a % MAX_COLORS; switch (a / MAX_COLORS) { case BG_BLACK: bg_colour = COLOUR_DARK; break; case BG_SAME: bg_colour = fg_colour; break; case BG_DARK: bg_colour = COLOUR_SHADE; break; default: assert((a >= BG_BLACK) && (a < BG_MAX * MAX_COLORS)); } /* Color change */ if (oa != a) { if (oa == COLOUR_WHITE) { /* From the default white to another color */ file_putf(fp, new_color_fmt, angband_color_table[fg_colour][1], angband_color_table[fg_colour][2], angband_color_table[fg_colour][3], angband_color_table[bg_colour][1], angband_color_table[bg_colour][2], angband_color_table[bg_colour][3]); } else if (fg_colour == COLOUR_WHITE && bg_colour == COLOUR_DARK) { /* From another color to the default white */ file_putf(fp, close_color_fmt); } else { /* Change colors */ file_putf(fp, change_color_fmt, angband_color_table[fg_colour][1], angband_color_table[fg_colour][2], angband_color_table[fg_colour][3], angband_color_table[bg_colour][1], angband_color_table[bg_colour][2], angband_color_table[bg_colour][3]); } /* Remember the last color */ oa = a; } /* Write the character and escape special HTML characters */ if (mode == 0) write_html_escape_char(fp, c); else { char mbseq[MB_LEN_MAX+1] = {0}; wctomb(mbseq, c); file_putf(fp, "%s", mbseq); } } /* End the row */ file_putf(fp, "\n"); } /* Close the last font-color tag if necessary */ if (oa != COLOUR_WHITE) file_putf(fp, close_color_fmt); if (mode == 0) { file_putf(fp, "</pre>\n"); file_putf(fp, "</body>\n"); file_putf(fp, "</html>\n"); } else { file_putf(fp, "[/COLOR][/BC][/TT][/CODE]\n"); } /* Close it */ file_close(fp); }
/* * Print some (colored) text to the screen at the current cursor position, * automatically "wrapping" existing text (at spaces) when necessary to * avoid placing any text into the last column, and clearing every line * before placing any text in that line. Also, allow "newline" to force * a "wrap" to the next line. Advance the cursor as needed so sequential * calls to this function will work correctly. * * Once this function has been called, the cursor should not be moved * until all the related "roff()" calls to the window are complete. * * This function will correctly handle any width up to the maximum legal * value of 256, though it works best for a standard 80 character width. */ void roff(cptr str, ...) { int x, y; int w, h; cptr s; byte a = TERM_WHITE; byte da = a; va_list vp; char buf[1024]; /* Begin the Varargs Stuff */ va_start(vp, str); /* Format the args, save the length */ (void)vstrnfmt(buf, 1024, str, &vp); /* End the Varargs Stuff */ va_end(vp); /* Obtain the size */ (void)Term_get_size(&w, &h); /* Obtain the cursor */ (void)Term_locate(&x, &y); /* Process the string */ for (s = buf; *s; s++) { char ch; /* Force wrap */ if (*s == '\n') { /* Wrap */ x = 0; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); continue; } /* Does this character match the escape code? */ if (*s == '$') { /* Scan the next character */ s++; /* Is it a colour specifier? */ if ((*s >= 'A') && (*s <= 'P')) { /* * Save the new colour * * Hack - this depends on ASCII symbols */ a = *s - 'A'; /* Hack -- fake monochrome */ if (!use_color) a = TERM_WHITE; continue; } /* Default colour change? */ else if (*s == 'Q') { /* Save current colour as 'default' */ da = a; continue; } /* Go back to default colour */ else if (*s == 'R') { a = da; continue; } /* * Hack XXX XXX - otherwise, ignore the dollar sign * * This makes "$$" turn into just "$". */ /* Stop if now reach null */ else if (*s == 0) break; } /* Clean up the char */ ch = (isprint(*s) ? *s : ' '); /* Wrap words as needed */ if ((x >= w - 1) && (ch != ' ')) { int i, n = 0; byte av[256]; char cv[256]; /* Wrap word */ if (x < w) { /* Scan existing text */ for (i = w - 2; i >= 0; i--) { /* Grab existing attr/char */ (void)Term_what(i, y, &av[i], &cv[i]); /* Break on space */ if (cv[i] == ' ') break; /* Track current word */ n = i; } } /* Special case */ if (n == 0) n = w; /* Clear line */ Term_erase(n, y, 255); /* Wrap */ x = 0; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); /* Wrap the word (if any) */ for (i = n; i < w - 1; i++) { /* Dump */ Term_addch(av[i], cv[i]); /* Advance (no wrap) */ if (++x > w) x = w; } } /* Dump */ Term_addch(a, ch); /* Advance */ if (++x > w) x = w; } }
/** * Write a character dump */ void write_character_dump(ang_file *fff) { int i, x, y; int a; wchar_t c; struct store *home = &stores[STORE_HOME]; struct object **home_list = mem_zalloc(sizeof(struct object *) * z_info->store_inven_max); char o_name[80]; char buf[1024]; char *p; /* Begin dump */ file_putf(fff, " [%s Character Dump]\n\n", buildid); /* Display player */ display_player(0); /* Dump part of the screen */ for (y = 1; y < 23; y++) { p = buf; /* Dump each row */ for (x = 0; x < 79; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Back up over spaces */ while ((p > buf) && (p[-1] == ' ')) --p; /* Terminate */ *p = '\0'; /* End the row */ file_putf(fff, "%s\n", buf); } /* Skip a line */ file_putf(fff, "\n"); /* Display player */ display_player(1); /* Dump part of the screen */ for (y = 11; y < 20; y++) { p = buf; /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Back up over spaces */ while ((p > buf) && (p[-1] == ' ')) --p; /* Terminate */ *p = '\0'; /* End the row */ file_putf(fff, "%s\n", buf); } /* Skip a line */ file_putf(fff, "\n"); /* Dump part of the screen */ for (y = 11; y < 20; y++) { p = buf; /* Dump each row */ for (x = 0; x < 39; x++) { /* Get the attr/char */ (void)(Term_what(x + 40, y, &a, &c)); /* Dump it */ p += wctomb(p, c); } /* Back up over spaces */ while ((p > buf) && (p[-1] == ' ')) --p; /* Terminate */ *p = '\0'; /* End the row */ file_putf(fff, "%s\n", buf); } /* Skip some lines */ file_putf(fff, "\n\n"); /* If dead, dump last messages -- Prfnoff */ if (player->is_dead) { i = messages_num(); if (i > 15) i = 15; file_putf(fff, " [Last Messages]\n\n"); while (i-- > 0) { file_putf(fff, "> %s\n", message_str((s16b)i)); } file_putf(fff, "\nKilled by %s.\n\n", player->died_from); } /* Dump the equipment */ file_putf(fff, " [Character Equipment]\n\n"); for (i = 0; i < player->body.count; i++) { struct object *obj = slot_object(player, i); if (!obj) continue; object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); file_putf(fff, "%c) %s\n", gear_to_label(obj), o_name); object_info_chardump(fff, obj, 5, 72); } file_putf(fff, "\n\n"); /* Dump the inventory */ file_putf(fff, "\n\n [Character Inventory]\n\n"); for (i = 0; i < z_info->pack_size; i++) { struct object *obj = player->upkeep->inven[i]; if (!obj) break; object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); file_putf(fff, "%c) %s\n", gear_to_label(obj), o_name); object_info_chardump(fff, obj, 5, 72); } file_putf(fff, "\n\n"); /* Dump the quiver */ file_putf(fff, "\n\n [Character Quiver]\n\n"); for (i = 0; i < z_info->quiver_size; i++) { struct object *obj = player->upkeep->quiver[i]; if (!obj) continue; object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); file_putf(fff, "%c) %s\n", gear_to_label(obj), o_name); object_info_chardump(fff, obj, 5, 72); } file_putf(fff, "\n\n"); /* Dump the Home -- if anything there */ store_stock_list(home, home_list, z_info->store_inven_max); if (home->stock_num) { /* Header */ file_putf(fff, " [Home Inventory]\n\n"); /* Dump all available items */ for (i = 0; i < z_info->store_inven_max; i++) { struct object *obj = home_list[i]; if (!obj) break; object_desc(o_name, sizeof(o_name), obj, ODESC_PREFIX | ODESC_FULL); file_putf(fff, "%c) %s\n", I2A(i), o_name); object_info_chardump(fff, obj, 5, 72); } /* Add an empty line */ file_putf(fff, "\n\n"); } /* Dump character history */ dump_history(fff); file_putf(fff, "\n\n"); /* Dump options */ file_putf(fff, " [Options]\n\n"); /* Dump options */ for (i = 0; i < OP_MAX; i++) { int opt; const char *title = ""; switch (i) { case OP_INTERFACE: title = "User interface"; break; case OP_BIRTH: title = "Birth"; break; default: continue; } file_putf(fff, " [%s]\n\n", title); for (opt = 0; opt < OPT_MAX; opt++) { if (option_type(opt) != i) continue; file_putf(fff, "%-45s: %s (%s)\n", option_desc(opt), player->opts.opt[opt] ? "yes" : "no ", option_name(opt)); } /* Skip some lines */ file_putf(fff, "\n"); } mem_free(home_list); }
/* * Print some (colored) text to the screen at the current cursor position, * automatically "wrapping" existing text (at spaces) when necessary to * avoid placing any text into the last column, and clearing every line * before placing any text in that line. Also, allow "newline" to force * a "wrap" to the next line. Advance the cursor as needed so sequential * calls to this function will work correctly. * * Once this function has been called, the cursor should not be moved * until all the related "text_out()" calls to the window are complete. * * This function will correctly handle any width up to the maximum legal * value of 256, though it works best for a standard 80 character width. */ void text_out_to_screen(byte a, const char *str) { int x, y; int wid, h; int wrap; const char *s; char buf[1024]; /* We use either ascii or system-specific encoding */ int encoding = (OPT(xchars_to_file)) ? SYSTEM_SPECIFIC : ASCII; /* Obtain the size */ (void)Term_get_size(&wid, &h); /* Obtain the cursor */ (void)Term_locate(&x, &y); /* Copy to a rewriteable string */ my_strcpy(buf, str, 1024); /* Translate it to 7-bit ASCII or system-specific format */ xstr_trans(buf, encoding); /* Use special wrapping boundary? */ if ((text_out_wrap > 0) && (text_out_wrap < wid)) wrap = text_out_wrap; else wrap = wid; /* Process the string */ for (s = buf; *s; s++) { char ch; /* Force wrap */ if (*s == '\n') { /* Wrap */ x = text_out_indent; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); x += text_out_pad; Term_gotoxy(x, y); continue; } /* Clean up the char */ ch = (my_isprint((unsigned char)*s) ? *s : ' '); /* Wrap words as needed */ if ((x >= wrap - 1) && (ch != ' ')) { int i, n = 0; byte av[256]; char cv[256]; /* Wrap word */ if (x < wrap) { /* Scan existing text */ for (i = wrap - 2; i >= 0; i--) { /* Grab existing attr/char */ Term_what(i, y, &av[i], &cv[i]); /* Break on space */ if (cv[i] == ' ') break; /* Track current word */ n = i; } } /* Special case */ if (n == 0) n = wrap; /* Clear line */ Term_erase(n, y, 255); /* Wrap */ x = text_out_indent; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); x += text_out_pad; Term_gotoxy(x, y); /* Wrap the word (if any) */ for (i = n; i < wrap - 1; i++) { /* Dump */ Term_addch(av[i], cv[i]); /* Advance (no wrap) */ if (++x > wrap) x = wrap; } } /* Dump */ Term_addch(a, ch); /* Advance */ if (++x > wrap) x = wrap; } }
/* * Draw a visible path over the squares between (x1,y1) and (x2,y2). * The path consists of "*", which are white except where there is a * monster, object or feature in the grid. * * This routine has (at least) three weaknesses: * - remembered objects/walls which are no longer present are not shown, * - squares which (e.g.) the player has walked through in the dark are * treated as unknown space. * - walls which appear strange due to hallucination aren't treated correctly. * * The first two result from information being lost from the dungeon arrays, * which requires changes elsewhere */ static int draw_path(u16b path_n, u16b *path_g, char *c, byte *a, int y1, int x1, int cur_tar_y, int cur_tar_x) { int i; bool on_screen; byte color_type; /* No path, so do nothing. */ if (path_n < 1) return (FALSE); /* The starting square is never drawn, but notice if it is being * displayed. In theory, it could be the last such square. */ on_screen = panel_contains(y1, x1); /* Draw the path. */ for (i = 0; i < path_n; i++) { /* Find the co-ordinates on the level. */ int y = GRID_Y(path_g[i]); int x = GRID_X(path_g[i]); byte this_a; char this_c; /* * As path[] is a straight line and the screen is oblong, * there is only section of path[] on-screen. * If the square being drawn is visible, this is part of it. * If none of it has been drawn, continue until some of it * is found or the last square is reached. * If some of it has been drawn, finish now as there are no * more visible squares to draw. * */ if (panel_contains(y,x)) on_screen = TRUE; else if (on_screen) break; else continue; /* Find the position on-screen */ move_cursor_relative(y,x); /* This square is being overwritten, so save the original. */ Term_what(Term->scr->cx, Term->scr->cy, a+i, c+i); /* Choose a colour. */ /* Visible monsters are orange. */ if (cave_m_idx[y][x] && mon_list[cave_m_idx[y][x]].ml) { monster_type *m_ptr = &mon_list[cave_m_idx[y][x]]; /*mimics act as objects*/ if (m_ptr->mimic_k_idx) color_type = TERM_YELLOW; else color_type = TERM_ORANGE; } /* Known objects are yellow. */ else if (cave_o_idx[y][x] && o_list[cave_o_idx[y][x]].marked) { color_type = TERM_YELLOW; } /* Effects are green */ else if ((cave_x_idx[y][x] > 0) && (cave_info[y][x] & (CAVE_SEEN | CAVE_MARK))) { color_type = TERM_GREEN; } /* Known walls are blue. */ else if (!cave_project_bold(y,x) && ((cave_info[y][x] & (CAVE_MARK)) || player_can_see_bold(y,x))) { color_type = TERM_BLUE; } /* Unknown squares are grey. */ else if (!(cave_info[y][x] & (CAVE_MARK)) && !player_can_see_bold(y,x)) { color_type = TERM_L_DARK; } /* Unoccupied squares are white. */ else { color_type = TERM_WHITE; } /* ALways use red for the current target square */ if ((cur_tar_y == y) && (cur_tar_x == x)) color_type = TERM_RED; /* Get the character */ if (!use_graphics) { this_a = color_type; this_c = '*'; } /* Graphics are being used */ else { this_a = color_to_attr[TILE_BALL_INFO][color_type]; this_c = color_to_char[TILE_BALL_INFO][color_type]; } /* Visual effects -- Display */ print_rel(this_c, this_a, y, x); } return i; }
/* * Hack -- load a screen dump from a file */ void do_cmd_load_screen(void) { s32b i, y, x; s32b wid, hgt; s32b len; byte a = 0; char c = ' '; bool okay = TRUE; PHYSFS_file *fff; char buf[1024]; /* Build the filename */ path_build(buf, 1024, TENGINE_DIR_USER, "dump.txt"); /* Append to the file */ fff = my_fopen(buf, "r"); /* Oops */ if (!fff) return; /* Retrieve the current screen size */ Term_get_size(&wid, &hgt); /* Enter "icky" mode */ character_icky++; /* Save the screen */ Term_save(); /* Clear the screen */ Term_clear(); /* Load the screen */ for (y = 0; okay; y++) { /* Get a line of data */ if (my_fgets(fff, buf, 1024)) okay = FALSE; /* Stop on blank line */ if (!buf[0]) break; /* Ignore off screen lines */ if (y >= hgt) continue; /* Get width */ len = strlen(buf); /* Truncate if it's longer than current screen width */ if (len > wid) len = wid; /* Show each row */ for (x = 0; x < len; x++) { /* Put the attr/char */ Term_draw(x, y, TERM_WHITE, buf[x]); } } /* Dump the screen */ for (y = 0; okay; y++) { /* Get a line of data */ if (my_fgets(fff, buf, 1024)) okay = FALSE; /* Stop on blank line */ if (!buf[0]) break; /* Ignore off screen lines */ if (y >= hgt) continue; /* Get width */ len = strlen(buf); /* Truncate if it's longer than current screen width */ if (len > wid) len = wid; /* Dump each row */ for (x = 0; x < len; x++) { /* Get the attr/char */ (void)(Term_what(x, y, &a, &c)); /* Look up the attr */ for (i = 0; i < 16; i++) { /* Use attr matches */ if (hack[i] == buf[x]) a = i; } /* Hack -- fake monochrome */ if (!use_color) a = TERM_WHITE; /* Put the attr/char */ Term_draw(x, y, a, c); } } /* Close it */ my_fclose(fff); /* Message */ msg_print("Screen dump loaded."); msg_print(NULL); /* Restore the screen */ Term_load(); /* Leave "icky" mode */ character_icky--; }