diff --git a/phantasia/fight.c b/phantasia/fight.c index cb44682..d391182 100644 --- a/phantasia/fight.c +++ b/phantasia/fight.c @@ -49,7 +49,7 @@ encounter(particular) if (Curmonster.m_type == SM_UNICORN) { if (Player.p_virgin) { - printw("You just subdued %s, thanks to the virgin.\n", Enemyname); + printw("You just subdued %s, thanks to the captive.\n", Enemyname); Player.p_virgin = FALSE; } else { printw("You just saw %s running away!\n", Enemyname); @@ -1031,7 +1031,7 @@ awardtreasure() break; case 2: - addstr("You have rescued a virgin. Will you be honorable ? "); + addstr("You have rescued a captive. Will you escort them home safely ? "); ch = getanswer("NY", FALSE); addstr("\n\n"); if (ch == 'Y') diff --git a/phantasia/gamesupport.c b/phantasia/gamesupport.c index 2bfc67f..5590a60 100644 --- a/phantasia/gamesupport.c +++ b/phantasia/gamesupport.c @@ -129,7 +129,7 @@ changestats(ingameflag) temp += 365; mvprintw(16, 40, "3:Lastused %d (%d)\n", playerp->p_lastused, temp); - mvprintw(18, 8, "4:Palantir %c 5:Blessing %c 6:Virgin %c 7:Blind %c", + mvprintw(18, 8, "4:Palantir %c 5:Blessing %c 6:Captive %c 7:Blind %c", flag[(int)playerp->p_palantir], flag[(int)playerp->p_blessing], flag[(int)playerp->p_virgin], @@ -368,8 +368,8 @@ changestats(ingameflag) bptr = &playerp->p_blessing; goto BALTER; - case '6': /* change virgin */ - prompt = "virgin"; + case '6': /* change captive */ + prompt = "captive"; bptr = &playerp->p_virgin; goto BALTER; diff --git a/phantasia/interplayer.c b/phantasia/interplayer.c index 3cb786c..936566e 100644 --- a/phantasia/interplayer.c +++ b/phantasia/interplayer.c @@ -241,7 +241,7 @@ battleplayer(foeplace) Player.p_shield = MAX(Player.p_shield, Other.p_shield); Player.p_quksilver = MAX(Player.p_quksilver, Other.p_quksilver); if (Other.p_virgin && !Player.p_virgin) { - mvaddstr(Lines++, 0, "You have rescued a virgin. Will you be honorable ? "); + mvaddstr(Lines++, 0, "You have rescued a captive. Will you escort them home safely ? "); if ((ch = getanswer("YN", FALSE)) == 'Y') Player.p_virgin = TRUE; else { diff --git a/phantasia/io.c b/phantasia/io.c index 66f2363..19866ba 100644 --- a/phantasia/io.c +++ b/phantasia/io.c @@ -30,7 +30,7 @@ getstring(cp, mx) clrtoeol(); /* clear any data after string */ refresh(); /* update screen */ - ch = getchar(); /* get character */ + ch = getch(); /* get character */ switch (ch) { case CH_ERASE: /* back up one character */ @@ -193,7 +193,7 @@ getanswer(choices, def) else alarm(600); /* long */ - ch = getchar(); + ch = getch(); alarm(0); /* turn off timeout */ diff --git a/phantasia/main.c b/phantasia/main.c index c370293..cf16ce2 100644 --- a/phantasia/main.c +++ b/phantasia/main.c @@ -116,8 +116,10 @@ main(argc, argv) /* NOTREACHED */ } +#ifndef __EMSCRIPTEN__ if (!isatty(0)) /* don't let non-tty's play */ cleanup(TRUE); +#endif /* NOTREACHED */ playinit(); /* set up to catch signals, init curses */ @@ -270,6 +272,51 @@ main(argc, argv) } } +#ifdef __EMSCRIPTEN__ +/* + * The browser build does what "setup" does, on every start: the binary monster data base + * (/phantasia/monsters) is made from monsters.asc, in memory, and the other data files, in + * /phantasia-data (which the page keeps in the browser), are created empty when they are missing. + */ +static void +fredy_setup_files() +{ + static const char *const files[] = { + _PATH_PEOPLE, _PATH_MESS, _PATH_LASTDEAD, _PATH_MOTD, _PATH_GOLD, _PATH_VOID, _PATH_SCORE, NULL + }; + const char *const *filename; + FILE *fp, *mfp; + + for (filename = files; *filename != NULL; ++filename) { + if ((fp = fopen(*filename, "a")) != NULL) + fclose(fp); + } + + if ((mfp = fopen(_PATH_MONST, "w")) == NULL) + error(_PATH_MONST); + if ((fp = fopen("/phantasia/monsters.asc", "r")) == NULL) + error("/phantasia/monsters.asc"); + Curmonster.m_o_strength = + Curmonster.m_o_speed = + Curmonster.m_maxspeed = + Curmonster.m_o_energy = + Curmonster.m_melee = + Curmonster.m_skirmish = 0.0; + while (fgets(Databuf, SZ_DATABUF, fp) != NULL) { + sscanf(&Databuf[24], "%lf%lf%lf%lf%lf%d%d%lf", + &Curmonster.m_strength, &Curmonster.m_brains, + &Curmonster.m_speed, &Curmonster.m_energy, + &Curmonster.m_experience, &Curmonster.m_treasuretype, + &Curmonster.m_type, &Curmonster.m_flock); + Databuf[24] = '\0'; + strcpy(Curmonster.m_name, Databuf); + fwrite((char *) &Curmonster, SZ_MONSTERSTRUCT, 1, mfp); + } + fclose(fp); + fclose(mfp); +} +#endif + void initialstate() { @@ -286,8 +333,14 @@ initialstate() Echo = TRUE; /* setup login name */ +#ifdef __EMSCRIPTEN__ + /* the browser has no user names */ + Login = "player"; + fredy_setup_files(); +#else if ((Login = getlogin()) == NULL) Login = getpwuid(getuid())->pw_name; +#endif /* open some files */ if ((Playersfp = fopen(_PATH_PEOPLE, "r+")) == NULL) @@ -751,7 +804,12 @@ recallplayer() { Echo = TRUE; +#ifdef __EMSCRIPTEN__ + /* a closed tab is not cheating: the browser build only has one player */ + if (0) +#else if (Player.p_status != S_OFF) +#endif /* player did not exit normally last * time */ { @@ -1001,6 +1059,9 @@ playinit() initscr(); /* turn on curses */ noecho(); /* do not echo input */ cbreak(); /* do not process erase, kill */ +#ifdef __EMSCRIPTEN__ + nl(); /* Enter is a newline */ +#endif #ifdef NCURSES_VERSION /* Ncurses needs some terminal mode fiddling */ tcgetattr(0, &tty); tty.c_iflag |= ICRNL; diff --git a/phantasia/misc.c b/phantasia/misc.c index d3f72b9..0f45ff7 100644 --- a/phantasia/misc.c +++ b/phantasia/misc.c @@ -437,7 +437,7 @@ allstatslist() mvprintw(15, 40, "Sword : %9.0f", Player.p_sword); mvprintw(16, 40, "Quickslver: %9.0f", Player.p_quksilver); - mvprintw(18, 0, "Blessing: %s Ring: %s Virgin: %s Palantir: %s", + mvprintw(18, 0, "Blessing: %s Ring: %s Captive: %s Palantir: %s", flags[(int)Player.p_blessing], flags[Player.p_ring.ring_type != R_NONE], flags[(int)Player.p_virgin], @@ -689,6 +689,12 @@ writerecord(playerp, place) fseek(Playersfp, place, SEEK_SET); fwrite((char *) playerp, SZ_PLAYERSTRUCT, 1, Playersfp); fflush(Playersfp); +#ifdef __EMSCRIPTEN__ + /* the page saves a data file in the browser when it is closed, so the file is closed and opened again */ + fclose(Playersfp); + if ((Playersfp = fopen(_PATH_PEOPLE, "r+")) == NULL) + error(_PATH_PEOPLE); +#endif } double @@ -939,6 +945,14 @@ void error(whichfile) const char *whichfile; { +#ifdef __EMSCRIPTEN__ + /* printw() is a macro in the curses layer of the browser build */ + if (Windows) { + clear(); + printw("An unrecoverable error has occurred reading %s. (%s)\n", whichfile, strerror(errno)); + } else + printf("An unrecoverable error has occurred reading %s. (%s)\n", whichfile, strerror(errno)); +#else int (*funcp)(const char *,...); if (Windows) { @@ -949,6 +963,7 @@ error(whichfile) (*funcp) ("An unrecoverable error has occurred reading %s. (%s)\n", whichfile, strerror(errno)); (*funcp) ("Please run 'setup' to determine the problem.\n"); +#endif cleanup(TRUE); /* NOTREACHED */ }