diff options
Diffstat (limited to 'src/cmovie.cc')
-rw-r--r-- | src/cmovie.cc | 500 |
1 files changed, 500 insertions, 0 deletions
diff --git a/src/cmovie.cc b/src/cmovie.cc new file mode 100644 index 00000000..85db2a32 --- /dev/null +++ b/src/cmovie.cc @@ -0,0 +1,500 @@ +/* File: cmovie.c */ + +/* Purpose: play cmovie files -DarkGod-Improv- */ + +#include "angband.h" + +/* + * Play a given cmovie + */ +s16b do_play_cmovie(cptr cmov_file) +{ + FILE *fff; + + int y, line = 0, x; + int delay; + + char *s; + + char buf[1024]; + char cbuf[90]; + char ch; + + char mode = 0; + + + /* Cmovie files are moved to the user directory on the multiuser systems */ + + /* Build the filename */ + path_build(buf, 1024, ANGBAND_DIR_CMOV, cmov_file); + + /* File type is "TEXT" */ + FILE_TYPE(FILE_TYPE_TEXT); + + /* Read the file */ + fff = my_fopen(buf, "r"); + + /* Failure */ + if (!fff) return ( -1); + + /* Save screen */ + character_icky = TRUE; + Term_save(); + Term_clear(); + + /* Give some usefull info */ + prt("While viewing the movie you can press Escape to exit, t/Space to switch between", 0, 0); + prt("fluid more and step by step mode and any other key to step a frame in step by", 1, 0); + prt("step mode.", 2, 0); + prt("You can press D to do an html screenshot of the current frame.", 3, 0); + prt("You can also use + and - to speed up/down the playing speed.", 5, 0); + prt("Press any key when ready.", 8, 0); + + inkey(); + + Term_clear(); + + line = -1; + + delay = 1; + + /* Init to white */ + for (x = 0; x < 80; x++) + { + cbuf[x] = 'w'; + } + + /* Parse */ + while (0 == my_fgets(fff, buf, 1024)) + { + /* Do not wait */ + inkey_scan = TRUE; + ch = inkey(); + + /* Stop */ + if (ch == ESCAPE) break; + + /* Change mode */ + else if (ch == 't') + { + mode = FALSE; + } + else if (ch == ' ') + { + mode = TRUE; + } + + /* Change speed */ + else if (ch == '+') + { + delay--; + if (delay < 0) delay = 0; + } + else if (ch == '-') + { + delay++; + if (delay > 5) delay = 5; + } + else if (ch == 'D') + { + do_cmd_html_dump(); + } + + line++; + + /* Skip comments and blank lines */ + if (!buf[0] || (buf[0] == '#')) continue; + + /* Verify correct "colon" format */ + if (buf[1] != ':') break; + + /* Clean screen */ + if (buf[0] == 'C') + { + Term_clear(); + + /* Next */ + continue; + } + + /* Displays a textbox */ + if (buf[0] == 'B') + { + int len = strlen(buf + 2); + + /* Clear the line */ + Term_erase(0, 0, 255); + + /* Display the message */ + c_put_str(TERM_VIOLET, "###", 0, 0); + c_put_str(TERM_ORANGE, buf + 2, 0, 3); + c_put_str(TERM_VIOLET, "###", 0, 3 + len); + c_put_str(TERM_WHITE, "(more)", 0, 6 + len); + + /* Next */ + continue; + } + + /* Wait a key */ + if (buf[0] == 'W') + { + inkey(); + + /* Next */ + continue; + } + + /* Sleep */ + if (buf[0] == 'S') + { + long msec; + + /* Scan for the values */ + if (1 != sscanf(buf + 2, "%ld:", &msec)) + { + return ( -2); + } + + if (!mode) + { + Term_xtra(TERM_XTRA_DELAY, msec); + } + else + { + bool_ stop = FALSE; + + while (TRUE) + { + ch = inkey(); + + /* Stop */ + if (ch == ESCAPE) + { + stop = TRUE; + break; + } + /* Change mode */ + else if (ch == 't') + { + mode = FALSE; + break; + } + /* Change mode */ + else if (ch == ' ') + { + if (mode) continue; + mode = TRUE; + break; + } + /* Change speed */ + else if (ch == '+') + { + delay--; + if (delay < 0) delay = 0; + } + else if (ch == '-') + { + delay++; + if (delay > 5) delay = 5; + } + else if (ch == 'D') + { + do_cmd_html_dump(); + } + else break; + } + if (stop) break; + } + + /* Next */ + continue; + } + + /* Get color for the NEXT L line */ + if (buf[0] == 'E') + { + /* Find the colon before the name */ + s = strchr(buf + 2, ':'); + + /* Verify that colon */ + if (!s) return ( -2); + + /* Nuke the colon, advance to the name */ + *s++ = '\0'; + + /* Paranoia -- require a name */ + if (!*s) return ( -2); + + /* Get the index */ + y = atoi(buf + 2); + + /* Copy */ + for (int i = 0; i < 80; i++) + { + cbuf[i] = s[i]; + } + + /* Next... */ + continue; + } + + /* Print a line */ + if (buf[0] == 'L') + { + /* Find the colon before the name */ + s = strchr(buf + 2, ':'); + + /* Verify that colon */ + if (!s) return ( -2); + + /* Nuke the colon, advance to the name */ + *s++ = '\0'; + + /* Paranoia -- require a name */ + if (!*s) return ( -2); + + /* Get the index */ + y = atoi(buf + 2); + + for (x = 0; x < 80; x++) + { + Term_putch(x, y, color_char_to_attr(cbuf[x]), s[x]); + + /* Reinit to white */ + cbuf[x] = 'w'; + } + Term_redraw_section(0, y, 79, y); + + /* Next... */ + continue; + } + + /* Update 1 char */ + if (buf[0] == 'P') + { + int x, y, a, c; + + /* Scan for the values */ + if (4 != sscanf(buf + 2, "%d:%d:%d:%d", + &x, &y, &c, &a)) + { + a = 'w'; + if (3 != sscanf(buf + 2, "%d:%d:%d", + &x, &y, &c)) return ( -2); + } + + Term_putch(x, y, color_char_to_attr(cbuf[x]), c); + Term_redraw_section(x, y, x + 1, y + 1); + + /* Next... */ + continue; + } + } + + /* Load screen */ + Term_load(); + character_icky = FALSE; + + /* Close */ + my_fclose(fff); + + return (0); +} + + +/* + * Start the recording of a cmovie + */ +void do_record_cmovie(cptr cmovie) +{ + char buf[1024]; + int fd = -1; + int y; + + + /* Build the filename */ + path_build(buf, 1024, ANGBAND_DIR_CMOV, cmovie); + + /* File type is "TEXT" */ + FILE_TYPE(FILE_TYPE_TEXT); + + /* Check for existing file */ + fd = fd_open(buf, O_RDONLY); + + /* Existing file */ + if (fd >= 0) + { + char out_val[160]; + + /* Close the file */ + (void)fd_close(fd); + + /* Build query */ + (void)sprintf(out_val, "Replace existing file %s? ", cmovie); + + /* Ask */ + if (get_check(out_val)) fd = -1; + } + + /* Be sure */ + if (!get_check("Ready to record(Press ctrl+D to enter a textual note while recording)?")) return; + + /* Open the non-existing file */ + if (fd < 0) movfile = my_fopen(buf, "w"); + + /* Invalid file */ + if (movfile == NULL) + { + msg_format("Cmovie recording failed!"); + + return; + } + + /* First thing: Record clear screen then enable the recording */ + fprintf(movfile, "# Generated by %s\n", + get_version_string()); + fprintf(movfile, "C:\n"); + last_paused = 0; + do_movies = 1; + cmovie_init_second(); + + /* Mega Hack, get the screen */ + for (y = 0; y < Term->hgt; y++) + { + cmovie_record_line(y); + } +} + + +/* + * Stop the recording + */ +void do_stop_cmovie() +{ + if (do_movies == 1) + { + do_movies = 0; + my_fclose(movfile); + } +} + + +/* + * Start a cmovie + */ +void do_start_cmovie() +{ + char name[90], rname[94]; + + + /* Should never happen */ + if (do_movies == 1) return; + + /* Default */ + sprintf(name, "%s", player_base); + + if (get_string("Cmovie name: ", name, 80)) + { + if (name[0] && (name[0] != ' ')) + { + sprintf(rname, "%s.cmv", name); + + if (get_check("Record(y), Play(n)?")) do_record_cmovie(rname); + else do_play_cmovie(rname); + } + } +} + + +void cmovie_clean_line(int y, char *abuf, char *cbuf) +{ + const byte *ap = Term->scr->a[y]; + const char *cp = Term->scr->c[y]; + + byte a; + char c; + + int x; + int wid, hgt; + int screen_wid, screen_hgt; + + + /* Retrieve current screen size */ + Term_get_size(&wid, &hgt); + + /* Calculate the size of dungeon map area */ + screen_wid = wid - (COL_MAP + 1); + screen_hgt = hgt - (ROW_MAP + 1); + + /* For the time being, assume 80 column display XXX XXX XXX */ + for (x = 0; x < wid; x++) + { + /* Convert dungeon map into default attr/chars */ + if (!character_icky && + ((x - COL_MAP) >= 0) && + ((x - COL_MAP) < screen_wid) && + ((y - ROW_MAP) >= 0) && + ((y - ROW_MAP) < screen_hgt)) + { + /* Retrieve default attr/char */ + map_info_default(y + panel_row_prt, x + panel_col_prt, &a, &c); + + abuf[x] = conv_color[a & 0xf]; + + if (c == '\0') cbuf[x] = ' '; + else cbuf[x] = c; + } + + else + { + abuf[x] = conv_color[ap[x] & 0xf]; + cbuf[x] = cp[x]; + } + } + + /* Null-terminate the prepared strings */ + abuf[x] = '\0'; + cbuf[x] = '\0'; +} + + +/* + * Write a record of a screen row into a cmovie file + */ +void cmovie_record_line(int y) +{ + char abuf[256]; + char cbuf[256]; + + cmovie_clean_line(y, abuf, cbuf); + + /* Write a colour record */ + fprintf(movfile, "E:%d:%.80s\n", y, abuf); + + /* Write a char record */ + fprintf(movfile, "L:%d:%.80s\n", y, cbuf); +} + + +/* + * Record a "text box" + */ +void do_cmovie_insert() +{ + char buf[81] = ""; + + /* Dont record */ + do_movies = 2; + + while (get_string("Textbox(ESC to end): ", buf, 80)) + { + fprintf(movfile, "B:%s\nW:\n", buf); + buf[0] = '\0'; + } + + /* We reinit the time as to not count the time the user needed ot enter the text */ + cmovie_init_second(); + + /* Continue recording */ + do_movies = 1; +} |