Angband.oook.cz
Angband.oook.cz
AboutVariantsLadderForumCompetitionComicScreenshotsFunniesLinks

Go Back   Angband Forums > Angband > Sil

Reply
 
Thread Tools Display Modes
Old October 7, 2017, 13:47   #1
Quirk
Apprentice
 
Join Date: Mar 2016
Posts: 54
Quirk is on a distinguished road
State of the update

As I imagine many of us don't have that much time to plough through threads to track what's going on I thought I'd write a summary of where things are with my new fork at present and where they're going. Long post, so I've split into spoilers.

RELEASED

Throwing Mastery and Momentum are gone.

Knock Back now lives where Throwing Mastery used to. If people like it there it stays as is. If they don't I'll consider how it may be buffed.

Impale, which lets you impale through two aligned enemies at once with a polearm or greatsword, is where Momentum was. I like this. It's staying.

Smashing Blow is where Knock Back was; it helps weapons to break through armor. This isn't super exciting. If people find it useful it stays.

Whirlwind Attack is no longer restricted by walls. 50% chance of halting after each time dealing damage.

Cruel Blow and Crippling Shot have been rebalanced to connect more at lower critical levels and less at higher critical levels. More work may be needed.

Filthy rags are gone.

Strength and Song of Freedom prerequisites are gone.

On early levels monsters are a little less alert.

Forges should now appear at 100, 500 and 900 feet. Other forges may be generated as well.

Quarterstaffs are now 2d4.

Quarterstaffs of Vaulting, Warhammers of Crushing, polearms of Piercing all added. Rings of Damage are now Rings of Archery (these are an actual thing, google thumb ring). Daggers of Murder are stealthy.

Channeling now auto-identifies staves and lets you get 2x as many charges out of them.

Non-unique monsters scared from the level net you experience.

Lorien and Mastery slightly boosted (effect is about +2 Song).

Slow Poison is now Antidote, and cures you.

Blunt weapons do bonus damage against armour. Armour only absorbs 3/4 of the damage the blunt weapon deals - this is better than 25% Sharpness where the amount of damage you would do is less than the armour roll. Damage dice remain low to compensate.

Careful Shot is now replaced by Rout, aim with +5 to hit against fleeing enemies. This gives casual archers a good tool particularly in the early game, but is unlikely to be overpowered late on.

Merged Clarity, Mind over Body and Resist Fear into a new skill, Indomitable.

Moved Strength in Adversity to Mind over Body's slot and had it boost Dex as well.

New skill - Defiance - saves you from a death-blow and sets your current and max HP equal to your Will.

256-colour terminal support.

mpa-sil screen centering fix merged.

Gorged status is gone. Eating more than you can stomach only spurs your digestion to new heights (you still shouldn't eat all your food at once, but you'll manage to get that herb or potion in when full).

Artifact with Throwing Mastery replaced.

Concentration prerequisite removed.

Song of Este prerequisite removed. Song of Este boosted a little. Now sustains stats as well. This is a temporary fix until the Song tree can be more properly reworked.

Deathblades gone, two new orc uniques added.


IN THE CODE

Just released.


UP NEXT

Redistribute Lorekeeper/Loremaster into having an actually useful 4-spot Perception skill (Alchemy, auto-ID potions and herbs, maybe horns and staves), having item ID in Smithing/Enchantment (2000 XP investment gets you there at present but I may readjust where it is in the tree). Add a Perception skill. Currently tempted by Second Sight, Perception boosts Evasion.

Rework or replace Smashing Blow - too good with huge axes.

Port more mpa-sil interface tweaks and ebering-sil bugfixes.

Fix putting the inscription !a (prompt before attacking) so it doesn't prompt for invisible monsters.

Look at traps, and whether they can be made more fun and less unfair.

Possibly fold Artistry into Smithing as an early fix before a proper reworking is done. Add a new Smithing skill - Reforge?

Add lyres, +Song off-hand items.


LONGER TERM

Look at artifact drop rates, and further changes to Smithing. Artistry likely to go. Contemplating some huge changes, but probably want to get a solid version closer to base Sil sorted and released.

Replace Song of Sharpness with something less niche, improve Song of Este, Lorien, Mastery.

Rework Song of Slaying - this likely needs to go along with a throne room update.

Extend Leaping to allow leaping over traps.

Maybe replace Follow-Through with Feint. Follow-Through is flavorful but doesn't seem very useful in practice.

Maybe get rid of -1 starting stats for Sindar and Naugrim.


ON HOLD FOR NOW

Replacing Focused Attack: I think the extra wait step in the UI makes for an awkwardly dull flow, but if it helps with stealth/melee builds it can stay until they're on a more solid foundation.

Altering Rapid Attack / Two Weapon Fighting: I want to see how other changes play out first. Particularly, Rapid Attack / Impale seems to potentially have some oomph.

Warhammers to 4d2: Warhammers of Crushing are 4d2, could be 4d3 with a fine one - a 4d5 two-handed Warhammer ignoring 25% of armor is probably a pretty usable weapon. If they need some love in a few weeks they may get tweaked again.

Last edited by Quirk; October 16, 2017 at 21:44.
Quirk is offline   Reply With Quote
Old October 8, 2017, 03:47   #2
nikheizen
Adept
 
Join Date: Jul 2015
Posts: 122
nikheizen is on a distinguished road
The best place for a changelog is in the release thread in my honest imho.
nikheizen is offline   Reply With Quote
Old October 8, 2017, 13:29   #3
Quirk
Apprentice
 
Join Date: Mar 2016
Posts: 54
Quirk is on a distinguished road
Quote:
Originally Posted by nikheizen View Post
The best place for a changelog is in the release thread in my honest imho.
This is not so much about the changelog, more the planning and the tracking against the planning. I would prefer discussion about what has been done to stay in the release thread, discussion about what will be done to stay in this one. I could have made the original planning thread into the tracking thread and that might have been better, but this one is here now.
Quirk is offline   Reply With Quote
Old October 8, 2017, 14:34   #4
Infinitum
Adept
 
Join Date: Oct 2013
Posts: 206
Infinitum is on a distinguished road
Aight. Your thoughts on removing the hunger/fuel clocks? Minimum depth superceeds both to the point where they don't really add anything to the game except small amounts of busywork. Vampirism/regeneration can be tied to minimum depth somehow, as can Unmourned-style enemies,
Infinitum is offline   Reply With Quote
Old October 8, 2017, 15:09   #5
Quirk
Apprentice
 
Join Date: Mar 2016
Posts: 54
Quirk is on a distinguished road
Quote:
Originally Posted by Infinitum View Post
Aight. Your thoughts on removing the hunger/fuel clocks? Minimum depth superceeds both to the point where they don't really add anything to the game except small amounts of busywork. Vampirism/regeneration can be tied to minimum depth somehow, as can Unmourned-style enemies,
I think they're a much more visible manifestation of the clock to newer players, and in some ways I find the minimum depth clock less elegant, as it is right now. If the minimum depth clock had some more flavorful and compelling manifestation, then maybe.

Another element though is that food and light makes for loot that is both low-value and useful; I think this is nice to have in the early levels.

I'm open to discussion though.
Quirk is offline   Reply With Quote
Old October 8, 2017, 19:20   #6
Gwarl
Swordsman
 
Join Date: Jan 2017
Posts: 369
Gwarl is on a distinguished road
A request:
Can you put up a repo and give this a name and a version number? And alter the source files to reflect the change of name. QuirkSil?
Gwarl is offline   Reply With Quote
Old October 8, 2017, 21:00   #7
Quirk
Apprentice
 
Join Date: Mar 2016
Posts: 54
Quirk is on a distinguished road
Quote:
Originally Posted by Gwarl View Post
A request:
Can you put up a repo and give this a name and a version number? And alter the source files to reflect the change of name. QuirkSil?
Sure, it's linked from the release thread. Currently it's Sil-Q, and the repo version saves as 1.3.1-q.

Link is https://github.com/sil-quirk/sil-q.

Changes today include monsters scared from the level netting you experience, and Channeling now letting you coax twice as many charges out of your staves (also auto-identify; Will bonus is gone for now). Fixed a nasty memory corruption bug with level generation (had to resort to valgrind), and tweaked Lorien and Mastery very slightly upward; it's difficult striking a balance between having Lorien being usable in the throne room and not murderously overpowered elsewhere so I'm staying a bit light-touch for now.

NOTE: Scaring monsters for exp has broken savefile compatibility between the release and the repo. Have also had to fix the tutorial.

Last edited by Quirk; October 8, 2017 at 21:45.
Quirk is offline   Reply With Quote
Old October 9, 2017, 11:37   #8
Quirk
Apprentice
 
Join Date: Mar 2016
Posts: 54
Quirk is on a distinguished road
I'm contemplating a simulationist overhaul to make the fortress of Angband a little more realistic.

This would, oddly, involve removing a lot of authentically Tolkien artifacts that simply should not be in Angband at the date we're playing (~ FA 469) - like Aeglos, Gil-galad's spear. I also don't see why Angband should be so littered with weapons specialised to killing orcs and spiders - these should be smithable by players, but only found as rare recoveries from human, elven and dwarven corpses. Weapons dropped by orcs and trolls and Easterlings should be weapons orcs and trolls and Easterlings might use, and most artifacts should be Morgoth-forged and carry serious drawbacks, apart from a few captured at times of Morgoth's strength (possibly many of these now remaning in dragon-hoards).

(I have toyed with overhauling generation to try and make something more like a real fortress, with kitchens and armories and barracks and dormitories, but this would be a pretty big undertaking).

It also would involve removing some uniques who shouldn't be in Angband at this date, like Ungoliant, as well as deathblades (and possibly the cats, who exist in an earlier version of the same canon - Tevildo becomes Thu becomes Sauron). Draugluin dies in the tale of Beren and Luthien, so is probably fair to keep. There is also quite a lot of canon support for varied and horrifying fell beasts of the Elder Days (e.g. Nazgul-steeds, the Watcher in the Water) which I think gives some room for interesting and horrifying additions to Angband's roster.

I started just wanting to do a rebalancing, and I'm not sure how many people would be put off by a turn in this direction; I'd be interested to hear any thoughts for or against.
Quirk is offline   Reply With Quote
Old October 9, 2017, 12:15   #9
Gwarl
Swordsman
 
Join Date: Jan 2017
Posts: 369
Gwarl is on a distinguished road
Okay this is up on angband.live now.

Here's the patched main-gcu.c so support 256-color terminals:


Code:
/* File: main-gcu.c */

/*
 * Copyright (c) 1997 Ben Harrison, and others
 *
 * This software may be copied and distributed for educational, research,
 * and not for profit purposes provided that this copyright and statement
 * are included in all such copies.
 */


/*
 * This file helps Angband run on Unix/Curses machines.
 *
 *
 * To use this file, you must define "USE_GCU" in the Makefile.
 *
 *
 * Note that this file is not "intended" to support non-Unix machines,
 * nor is it intended to support VMS or other bizarre setups.
 *
 * Also, this package assumes that the underlying "curses" handles both
 * the "nonl()" and "cbreak()" commands correctly, see the "OPTION" below.
 *
 * This code should work with most versions of "curses" or "ncurses",
 * and the "main-ncu.c" file (and USE_NCU define) are no longer used.
 *
 * See also "USE_CAP" and "main-cap.c" for code that bypasses "curses"
 * and uses the "termcap" information directly, or even bypasses the
 * "termcap" information and sends direct vt100 escape sequences.
 *
 * This file provides up to 4 term windows.
 *
 * This file will attempt to redefine the screen colors to conform to
 * standard Angband colors.  It will only do so if the terminal type
 * indicates that it can do so.  See the page:
 *
 *     http://www.umr.edu/~keldon/ang-patch/ncurses_color.html
 *
 * for information on this.
 *
 * Consider the use of "savetty()" and "resetty()".  XXX XXX XXX
 */


#include "angband.h"


#ifdef USE_GCU

#include "main.h"

/*
 * Hack -- play games with "bool" and "term"
 */
#undef bool

/* Avoid 'struct term' name conflict with <curses.h> (via <term.h>) on AIX */
#define term System_term

/*
 * Include the proper "header" file
 */
#ifdef USE_NCURSES
# include <ncurses.h>
#else
# include <curses.h>
#endif

#undef term


#ifdef HAVE_CAN_CHANGE_COLOR

/*
 * Try redefining the colors at startup.
 */
#define REDEFINE_COLORS

#endif /* HAVE_CAN_CHANGE_COLOR */


/*
 * Hack -- try to guess which systems use what commands
 * Hack -- allow one of the "USE_Txxxxx" flags to be pre-set.
 * Mega-Hack -- try to guess when "POSIX" is available.
 * If the user defines two of these, we will probably crash.
 */
#if !defined(USE_TPOSIX)
# if !defined(USE_TERMIO) && !defined(USE_TCHARS)
#  if defined(_POSIX_VERSION)
#   define USE_TPOSIX
#  else
#   if defined(USG) || defined(linux) || defined(SOLARIS)
#    define USE_TERMIO
#   else
#    define USE_TCHARS
#   endif
#  endif
# endif
#endif

/*
 * Hack -- Amiga uses "fake curses" and cannot do any of this stuff
 */
#if defined(AMIGA)
# undef USE_TPOSIX
# undef USE_TERMIO
# undef USE_TCHARS
#endif




/*
 * POSIX stuff
 */
#ifdef USE_TPOSIX
# include <sys/ioctl.h>
# include <termios.h>
#endif

/*
 * One version needs these files
 */
#ifdef USE_TERMIO
# include <sys/ioctl.h>
# include <termio.h>
#endif

/*
 * The other needs these files
 */
#ifdef USE_TCHARS
# include <sys/ioctl.h>
# include <sys/resource.h>
# include <sys/param.h>
# include <sys/file.h>
# include <sys/types.h>
#endif


/*
 * XXX XXX Hack -- POSIX uses "O_NONBLOCK" instead of "O_NDELAY"
 *
 * They should both work due to the "(i != 1)" test below.
 */
#ifndef O_NDELAY
# define O_NDELAY O_NONBLOCK
#endif


/*
 * OPTION: some machines lack "cbreak()"
 * On these machines, we use an older definition
 */
/* #define cbreak() crmode() */


/*
 * OPTION: some machines cannot handle "nonl()" and "nl()"
 * On these machines, we can simply ignore those commands.
 */
/* #define nonl() */
/* #define nl() */


/*
 * Save the "normal" and "angband" terminal settings
 */

#ifdef USE_TPOSIX

static struct termios  norm_termios;

static struct termios  game_termios;

#endif

#ifdef USE_TERMIO

static struct termio  norm_termio;

static struct termio  game_termio;

#endif

#ifdef USE_TCHARS

static struct ltchars norm_special_chars;
static struct sgttyb  norm_ttyb;
static struct tchars  norm_tchars;
static int            norm_local_chars;

static struct ltchars game_special_chars;
static struct sgttyb  game_ttyb;
static struct tchars  game_tchars;
static int            game_local_chars;

#endif

/*
 * Information about a term
 */
typedef struct term_data term_data;

struct term_data
{
	term t;                 /* All term info */

	WINDOW *win;            /* Pointer to the curses window */
};

/* Max number of windows on screen */
#define MAX_TERM_DATA 4

/* Information about our windows */
static term_data data[MAX_TERM_DATA];


/*
 * Hack -- Number of initialized "term" structures
 */
static int active = 0;


#ifdef A_COLOR

/*
 * Hack -- define "A_BRIGHT" to be "A_BOLD", because on many
 * machines, "A_BRIGHT" produces ugly "inverse" video.
 */
#ifndef A_BRIGHT
# define A_BRIGHT A_BOLD
#endif

/*
 * Software flag -- we are allowed to use color
 */
static int can_use_color = FALSE;

/*
 * Software flag -- we are allowed to change the colors
 */
static int can_fix_color = FALSE;

/*
 * Simple Angband to Curses color conversion table
 */
static int colortable[16];

#endif

/*
 * Background color we should draw with; either BLACK or DEFAULT
 */
static int bg_color = COLOR_BLACK;


/*
 * Place the "keymap" into its "normal" state
 */
static void keymap_norm(void)
{

#ifdef USE_TPOSIX

	/* restore the saved values of the special chars */
	(void)tcsetattr(0, TCSAFLUSH, &norm_termios);

#endif

#ifdef USE_TERMIO

	/* restore the saved values of the special chars */
	(void)ioctl(0, TCSETA, (char *)&norm_termio);

#endif

#ifdef USE_TCHARS

	/* restore the saved values of the special chars */
	(void)ioctl(0, TIOCSLTC, (char *)&norm_special_chars);
	(void)ioctl(0, TIOCSETP, (char *)&norm_ttyb);
	(void)ioctl(0, TIOCSETC, (char *)&norm_tchars);
	(void)ioctl(0, TIOCLSET, (char *)&norm_local_chars);

#endif

}


/*
 * Place the "keymap" into the "game" state
 */
static void keymap_game(void)
{

#ifdef USE_TPOSIX

	/* restore the saved values of the special chars */
	(void)tcsetattr(0, TCSAFLUSH, &game_termios);

#endif

#ifdef USE_TERMIO

	/* restore the saved values of the special chars */
	(void)ioctl(0, TCSETA, (char *)&game_termio);

#endif

#ifdef USE_TCHARS

	/* restore the saved values of the special chars */
	(void)ioctl(0, TIOCSLTC, (char *)&game_special_chars);
	(void)ioctl(0, TIOCSETP, (char *)&game_ttyb);
	(void)ioctl(0, TIOCSETC, (char *)&game_tchars);
	(void)ioctl(0, TIOCLSET, (char *)&game_local_chars);

#endif

}


/*
 * Save the normal keymap
 */
static void keymap_norm_prepare(void)
{

#ifdef USE_TPOSIX

	/* Get the normal keymap */
	tcgetattr(0, &norm_termios);

#endif

#ifdef USE_TERMIO

	/* Get the normal keymap */
	(void)ioctl(0, TCGETA, (char *)&norm_termio);

#endif

#ifdef USE_TCHARS

	/* Get the normal keymap */
	(void)ioctl(0, TIOCGETP, (char *)&norm_ttyb);
	(void)ioctl(0, TIOCGLTC, (char *)&norm_special_chars);
	(void)ioctl(0, TIOCGETC, (char *)&norm_tchars);
	(void)ioctl(0, TIOCLGET, (char *)&norm_local_chars);

#endif

}


/*
 * Save the keymaps (normal and game)
 */
static void keymap_game_prepare(void)
{

#ifdef USE_TPOSIX

	/* Acquire the current mapping */
	tcgetattr(0, &game_termios);

	/* Force "Ctrl-C" to interupt */
	game_termios.c_cc[VINTR] = (char)3;

	/* Force "Ctrl-Z" to suspend */
	game_termios.c_cc[VSUSP] = (char)26;

	/* Hack -- Leave "VSTART/VSTOP" alone */

	/* Disable the standard control characters */
	game_termios.c_cc[VQUIT] = (char)-1;
	game_termios.c_cc[VERASE] = (char)-1;
	game_termios.c_cc[VKILL] = (char)-1;
	game_termios.c_cc[VEOF] = (char)-1;
	game_termios.c_cc[VEOL] = (char)-1;

	/* Normally, block until a character is read */
	game_termios.c_cc[VMIN] = 1;
	game_termios.c_cc[VTIME] = 0;

#endif

#ifdef USE_TERMIO

	/* Acquire the current mapping */
	(void)ioctl(0, TCGETA, (char *)&game_termio);

	/* Force "Ctrl-C" to interupt */
	game_termio.c_cc[VINTR] = (char)3;

	/* Force "Ctrl-Z" to suspend */
	game_termio.c_cc[VSUSP] = (char)26;

	/* Hack -- Leave "VSTART/VSTOP" alone */

	/* Disable the standard control characters */
	game_termio.c_cc[VQUIT] = (char)-1;
	game_termio.c_cc[VERASE] = (char)-1;
	game_termio.c_cc[VKILL] = (char)-1;
	game_termio.c_cc[VEOF] = (char)-1;
	game_termio.c_cc[VEOL] = (char)-1;

#if 0
	/* Disable the non-posix control characters */
	game_termio.c_cc[VEOL2] = (char)-1;
	game_termio.c_cc[VSWTCH] = (char)-1;
	game_termio.c_cc[VDSUSP] = (char)-1;
	game_termio.c_cc[VREPRINT] = (char)-1;
	game_termio.c_cc[VDISCARD] = (char)-1;
	game_termio.c_cc[VWERASE] = (char)-1;
	game_termio.c_cc[VLNEXT] = (char)-1;
	game_termio.c_cc[VSTATUS] = (char)-1;
#endif

	/* Normally, block until a character is read */
	game_termio.c_cc[VMIN] = 1;
	game_termio.c_cc[VTIME] = 0;

#endif

#ifdef USE_TCHARS

	/* Get the default game characters */
	(void)ioctl(0, TIOCGETP, (char *)&game_ttyb);
	(void)ioctl(0, TIOCGLTC, (char *)&game_special_chars);
	(void)ioctl(0, TIOCGETC, (char *)&game_tchars);
	(void)ioctl(0, TIOCLGET, (char *)&game_local_chars);

	/* Force suspend (^Z) */
	game_special_chars.t_suspc = (char)26;

	/* Cancel some things */
	game_special_chars.t_dsuspc = (char)-1;
	game_special_chars.t_rprntc = (char)-1;
	game_special_chars.t_flushc = (char)-1;
	game_special_chars.t_werasc = (char)-1;
	game_special_chars.t_lnextc = (char)-1;

	/* Force interupt (^C) */
	game_tchars.t_intrc = (char)3;

	/* Force start/stop (^Q, ^S) */
	game_tchars.t_startc = (char)17;
	game_tchars.t_stopc = (char)19;

	/* Cancel some things */
	game_tchars.t_quitc = (char)-1;
	game_tchars.t_eofc = (char)-1;
	game_tchars.t_brkc = (char)-1;

#endif

}




/*
 * Suspend/Resume
 */
static errr Term_xtra_gcu_alive(int v)
{
	int x, y;


	/* Suspend */
	if (!v)
	{
		/* Go to normal keymap mode */
		keymap_norm();

		/* Restore modes */
		nocbreak();
		echo();
		nl();

		/* Hack -- make sure the cursor is visible */
		Term_xtra(TERM_XTRA_SHAPE, 1);

		/* Flush the curses buffer */
		(void)refresh();

		/* Get current cursor position */
		getyx(curscr, y, x);

		/* Move the cursor to bottom right corner */
		mvcur(y, x, LINES - 1, 0);

		/* Exit curses */
		endwin();

		/* Flush the output */
		(void)fflush(stdout);
	}

	/* Resume */
	else
	{
		/* Refresh */
		/* (void)touchwin(curscr); */
		/* (void)wrefresh(curscr); */

		/* Restore the settings */
		cbreak();
		noecho();
		nonl();

		/* Go to angband keymap mode */
		keymap_game();
	}

	/* Success */
	return (0);
}


#ifdef USE_NCURSES
const char help_gcu[] = "NCurses, for terminal console, subopts -b(ig screen)";
#else /* USE_NCURSES */
const char help_gcu[] = "Curses, for terminal console, subopts -b(ig screen)";
#endif /* USE_NCURSES */


/*
 * Init the "curses" system
 */
static void Term_init_gcu(term *t)
{
	term_data *td = (term_data *)(t->data);

#ifdef USE_GETCH
	/*
	 * This is necessary to keep the first call to getch()
	 * from clearing the screen
	 */
	wrefresh(stdscr);
#endif /* USE_GETCH */

	/* Count init's, handle first */
	if (active++ != 0) return;

	/* Erase the window */
	(void)wclear(td->win);

	/* Reset the cursor */
	(void)wmove(td->win, 0, 0);

	/* Flush changes */
	(void)wrefresh(td->win);

	/* Game keymap */
	keymap_game();
}


/*
 * Nuke the "curses" system
 */
static void Term_nuke_gcu(term *t)
{
	int x, y;
	term_data *td = (term_data *)(t->data);

	/* Delete this window */
	delwin(td->win);

	/* Count nuke's, handle last */
	if (--active != 0) return;

	/* Hack -- make sure the cursor is visible */
	Term_xtra(TERM_XTRA_SHAPE, 1);

#ifdef A_COLOR
	/* Reset colors to defaults */
	start_color();
#endif

	/* Get current cursor position */
	getyx(curscr, y, x);

	/* Move the cursor to bottom right corner */
	mvcur(y, x, LINES - 1, 0);

	/* Flush the curses buffer */
	(void)refresh();

	/* Exit curses */
	endwin();

	/* Flush the output */
	(void)fflush(stdout);

	/* Normal keymap */
	keymap_norm();
}




#ifdef USE_GETCH

/*
 * Process events, with optional wait
 */
static errr Term_xtra_gcu_event(int v)
{
	int i, k;

	/* Wait */
	if (v)
	{
		/* Paranoia -- Wait for it */
		nodelay(stdscr, FALSE);

		/* Get a keypress */
		i = getch();

		/* Mega-Hack -- allow graceful "suspend" */
		for (k = 0; (k < 10) && (i == ERR); k++) i = getch();

		/* Broken input is special */
		if (i == ERR) exit_game_panic();
		if (i == EOF) exit_game_panic();
	}

	/* Do not wait */
	else
	{
		/* Do not wait for it */
		nodelay(stdscr, TRUE);

		/* Check for keypresses */
		i = getch();

		/* Wait for it next time */
		nodelay(stdscr, FALSE);

		/* None ready */
		if (i == ERR) return (1);
		if (i == EOF) return (1);
	}

	/* Enqueue the keypress */
	Term_keypress(i);

	/* Success */
	return (0);
}

#else	/* USE_GETCH */

/*
 * Process events (with optional wait)
 */
static errr Term_xtra_gcu_event(int v)
{
	int i, k;

	char buf[2];

	/* Wait */
	if (v)
	{
		/* Wait for one byte */
		i = read(0, buf, 1);

		/* Hack -- Handle bizarre "errors" */
		if ((i <= 0) && (errno != EINTR)) exit_game_panic();
	}

	/* Do not wait */
	else
	{
		/* Get the current flags for stdin */
		k = fcntl(0, F_GETFL, 0);

		/* Oops */
		if (k < 0) return (1);

		/* Tell stdin not to block */
		if (fcntl(0, F_SETFL, k | O_NDELAY) < 0) return (1);

		/* Read one byte, if possible */
		i = read(0, buf, 1);

		/* Replace the flags for stdin */
		if (fcntl(0, F_SETFL, k)) return (1);
	}

	/* Ignore "invalid" keys */
	if ((i != 1) || (!buf[0])) return (1);

	/* Enqueue the keypress */
	Term_keypress(buf[0]);

	/* Success */
	return (0);
}

#endif	/* USE_GETCH */

static int scale_color(int i, int j, int scale)
{
    return (angband_color_table[i][j] * (scale - 1) + 127) / 255;
}

static int create_color(int i, int scale)
{
    int r = scale_color(i, 1, scale);
    int g = scale_color(i, 2, scale);
    int b = scale_color(i, 3, scale);
    int rgb = 16 + scale * scale * r + scale * g + b;
    /* In the case of white and black we need to use the ANSI colors */
    if (r == g && g == b)
    {
        if (b == 0) rgb = 0;
        if (b == scale) rgb = 15;
    }
    return rgb;
}

/*
 * React to changes
 */
static errr Term_xtra_gcu_react(void)
{

#ifdef A_COLOR
    if (COLORS == 256 || COLORS == 88)
    {
        /* CTK: I snagged this color handling from current Vanilla */
        /* If we have more than 16 colors, find the best matches. These numbers
        * correspond to xterm/rxvt's builtin color numbers--they do not
        * correspond to curses' constants OR with curses' color pairs.
        *
        * XTerm has 216 (6*6*6) RGB colors, with each RGB setting 0-5.
        * RXVT has 64 (4*4*4) RGB colors, with each RGB setting 0-3.
        *
        * Both also have the basic 16 ANSI colors, plus some extra grayscale
        * colors which we do not use.
        */
        int i;
        int scale = COLORS == 256 ? 6 : 4;
        for (i = 0; i < 16; i++)
        {
            int fg = create_color(i, scale);
            init_pair(i + 1, fg, bg_color);
            colortable[i] = COLOR_PAIR(i + 1) | A_NORMAL;
        }
    }

#endif

	/* Success */
	return (0);
}


/*
 * Handle a "special request"
 */
static errr Term_xtra_gcu(int n, int v)
{
	term_data *td = (term_data *)(Term->data);

	/* Analyze the request */
	switch (n)
	{
		/* Clear screen */
		case TERM_XTRA_CLEAR:
		touchwin(td->win);
		(void)wclear(td->win);
		return (0);

		/* Make a noise */
		case TERM_XTRA_NOISE:
		(void)write(1, "\007", 1);
		return (0);

		/* Flush the Curses buffer */
		case TERM_XTRA_FRESH:
		(void)wrefresh(td->win);
		return (0);

#ifdef USE_CURS_SET

		/* Change the cursor visibility */
		case TERM_XTRA_SHAPE:
		curs_set(v);
		return (0);

#endif

		/* Suspend/Resume curses */
		case TERM_XTRA_ALIVE:
		return (Term_xtra_gcu_alive(v));

		/* Process events */
		case TERM_XTRA_EVENT:
		return (Term_xtra_gcu_event(v));

		/* Flush events */
		case TERM_XTRA_FLUSH:
		while (!Term_xtra_gcu_event(FALSE));
		return (0);

		/* Delay */
		case TERM_XTRA_DELAY:
		if (v > 0) usleep(1000 * v);
		return (0);

		/* React to events */
		case TERM_XTRA_REACT:
		Term_xtra_gcu_react();
		return (0);
	}

	/* Unknown */
	return (1);
}


/*
 * Actually MOVE the hardware cursor
 */
static errr Term_curs_gcu(int x, int y)
{
	term_data *td = (term_data *)(Term->data);

	/* Literally move the cursor */
	wmove(td->win, y, x);

	/* Success */
	return (0);
}


/*
 * Erase a grid of space
 * Hack -- try to be "semi-efficient".
 */
static errr Term_wipe_gcu(int x, int y, int n)
{
	term_data *td = (term_data *)(Term->data);

	/* Place cursor */
	wmove(td->win, y, x);

	/* Clear to end of line */
	if (x + n >= td->t.wid)
	{
		wclrtoeol(td->win);
	}

	/* Clear some characters */
	else
	{
		while (n-- > 0) waddch(td->win, ' ');
	}

	/* Success */
	return (0);
}


/*
 * Place some text on the screen using an attribute
 */
static errr Term_text_gcu(int x, int y, int n, byte a, cptr s)
{
	term_data *td = (term_data *)(Term->data);

	int i;

#ifdef A_COLOR
	/* Set the color */
	if (can_use_color) wattrset(td->win, colortable[a & 0x0F]);
#endif

	/* Move the cursor */
	wmove(td->win, y, x);

	/* Draw each character */
	for (i = 0; i < n; i++)
	{
#ifdef USE_GRAPHICS
		int pic;

		/* Special character */
		if (use_graphics && (s[i] & 0x80))
		{
			/* Determine picture to use */
			switch (s[i] & 0x7F)
			{

#ifdef ACS_CKBOARD
				/* Wall */
				case '#':
					pic = ACS_CKBOARD;
					break;
#endif /* ACS_CKBOARD */

#ifdef ACS_BOARD
				/* Mineral vein */
				case '%':
					pic = ACS_BOARD;
					break;
#endif /* ACS_BOARD */

				/* XXX */
				default:
					pic = '?';
					break;
			}

			/* Draw the picture */
			waddch(td->win, pic);

			/* Next character */
			continue;
		}
#endif /* USE_GRAPHICS */

		/* Draw a normal character */
		waddch(td->win, (byte)s[i]);
	}

	/* Success */
	return (0);
}


/*
 * Create a window for the given "term_data" argument.
 *
 * Assumes legal arguments.
 */
static errr term_data_init_gcu(term_data *td, int rows, int cols, int y, int x)
{
	term *t = &td->t;

	/* Create new window */
	td->win = newwin(rows, cols, y, x);

	/* Check for failure */
	if (!td->win)
	{
		/* Error */
		quit("Failed to setup curses window.");
	}

	/* Initialize the term */
	term_init(t, cols, rows, 256);

	/* Avoid bottom right corner */
	t->icky_corner = TRUE;

	/* Erase with "white space" */
	t->attr_blank = TERM_WHITE;
	t->char_blank = ' ';

	/* Set some hooks */
	t->init_hook = Term_init_gcu;
	t->nuke_hook = Term_nuke_gcu;

	/* Set some more hooks */
	t->text_hook = Term_text_gcu;
	t->wipe_hook = Term_wipe_gcu;
	t->curs_hook = Term_curs_gcu;
	t->xtra_hook = Term_xtra_gcu;

	/* Save the data */
	t->data = td;

	/* Activate it */
	Term_activate(t);

	/* Success */
	return (0);
}


static void hook_quit(cptr str)
{
	/* Unused */
	(void)str;

	/* Exit curses */
	endwin();
}


/*
 * Prepare "curses" for use by the file "z-term.c"
 *
 * Installs the "hook" functions defined above, and then activates
 * the main screen "term", which clears the screen and such things.
 *
 * Someone should really check the semantics of "initscr()"
 */
errr init_gcu(int argc, char **argv)
{
	int i;

	int num_term = MAX_TERM_DATA, next_win = 0;

	bool use_big_screen = FALSE;


	/* Parse args */
	for (i = 1; i < argc; i++)
	{
		if (prefix(argv[i], "-b"))
		{
			use_big_screen = TRUE;
			continue;
		}

		plog_fmt("Ignoring option: %s", argv[i]);
	}


	/* Extract the normal keymap */
	keymap_norm_prepare();

	/* Initialize */
	if (initscr() == NULL) return (-1);

	/* RAW */
	raw();

	/* Activate hooks */
	quit_aux = hook_quit;
	core_aux = hook_quit;

	/* Require standard size screen */
	if ((LINES < 24) || (COLS < 80))
	{
		quit("Angband needs at least an 80x24 'curses' screen");
	}


#ifdef USE_GRAPHICS

	/* Set graphics */
	if (arg_graphics)
	{
		use_graphics = GRAPHICS_PSEUDO;
		ANGBAND_GRAF = "pseudo";
	}


#endif /* USE_GRAPHICS */

#ifdef A_COLOR

	/*** Init the Color-pairs and set up a translation table ***/

	/* Do we have color, and enough color, available? */
	can_use_color = ((start_color() != ERR) && has_colors() &&
	                 (COLORS >= 8) && (COLOR_PAIRS >= 8));

#ifdef REDEFINE_COLORS

	/* Should we use curses' "default color" */
	if(use_default_colors() == OK)
		bg_color = -1;

#endif

	/* Attempt to use customized colors */
	if (can_fix_color)
	{
		/* Prepare the color pairs */
		for (i = 1; i <= 8; i++)
		{
			/* Reset the color */
			if (init_pair(i + 1, i, bg_color) == ERR)
			{
				quit("Color pair init failed");
			}

			/* Set up the colormap */
			colortable[i - 1] = (COLOR_PAIR(i) | A_NORMAL);
			colortable[i + 7] = (COLOR_PAIR(i) | A_BRIGHT);
		}

		/* Take account of "gamma correction" XXX XXX XXX */

		/* Prepare the "Angband Colors" */
		Term_xtra_gcu_react();
	}

	/* Attempt to use colors */
	else if (can_use_color)
	{
		/* Color-pair 0 is *always* WHITE on BLACK */

		/* Prepare the color pairs */
		init_pair(1, COLOR_RED,     bg_color);
		init_pair(2, COLOR_GREEN,   bg_color);
		init_pair(3, COLOR_YELLOW,  bg_color);
		init_pair(4, COLOR_BLUE,    bg_color);
		init_pair(5, COLOR_MAGENTA, bg_color);
		init_pair(6, COLOR_CYAN,    bg_color);
		init_pair(7, COLOR_BLACK,   bg_color);

		/* Prepare the colors */
		colortable[0] = (COLOR_PAIR(7) | A_NORMAL);	/* Black */
		colortable[1] = (COLOR_PAIR(0) | A_BRIGHT);	/* White */
		colortable[2] = (COLOR_PAIR(0) | A_NORMAL);	/* Grey XXX */
		colortable[3] = (COLOR_PAIR(1) | A_BRIGHT);	/* Orange XXX */
		colortable[4] = (COLOR_PAIR(1) | A_NORMAL);	/* Red */
		colortable[5] = (COLOR_PAIR(2) | A_NORMAL);	/* Green */
		colortable[6] = (COLOR_PAIR(4) | A_NORMAL);	/* Blue */
		colortable[7] = (COLOR_PAIR(3) | A_NORMAL);	/* Umber */
		colortable[8] = (COLOR_PAIR(7) | A_BRIGHT);	/* Dark-grey XXX */
		colortable[9] = (COLOR_PAIR(0) | A_NORMAL);	/* Light-grey XXX */
		colortable[10] = (COLOR_PAIR(5) | A_NORMAL);	/* Purple */
		colortable[11] = (COLOR_PAIR(3) | A_BRIGHT);	/* Yellow */
		colortable[12] = (COLOR_PAIR(5) | A_BRIGHT);	/* Light Red XXX */
		colortable[13] = (COLOR_PAIR(2) | A_BRIGHT);	/* Light Green */
		colortable[14] = (COLOR_PAIR(4) | A_BRIGHT);	/* Light Blue */
		colortable[15] = (COLOR_PAIR(3) | A_NORMAL);	/* Light Umber XXX */
	}

#endif


	/*** Low level preparation ***/

#ifdef USE_GETCH

	/* Paranoia -- Assume no waiting */
	nodelay(stdscr, FALSE);

#endif

	/* Prepare */
	cbreak();
	noecho();
	nonl();

	/* Extract the game keymap */
	keymap_game_prepare();


	/*** Now prepare the term(s) ***/

	/* Big screen -- one big term */
	if (use_big_screen)
	{
		/* Create a term */
		term_data_init_gcu(&data[0], LINES, COLS, 0, 0);

		/* Remember the term */
		angband_term[0] = &data[0].t;
	}

	/* No big screen -- create as many term windows as possible */
	else
	{
		/*
		 * If we have a REALLY big screen, try to put any
		 * extra real estate into the upper-left window.
		 * Hack -- these constants rely on a-priori knowledge
		 * of the sort of things that go in the windows.
		 *
		 * This patch is by 'bron' from the Angband Forum
		 * under the directions: 'Feel free to use this (or not) as you see fit.'
		 */

		/* Minimum size for UpperLeft window */
		const int ul_min_rows = 24;
		const int ul_min_cols = 80;

		/* Maximum (useful) columns for UpperRight window */
		const int ur_max_cols = 80;

		/* Maximum (useful) rows for LowerLeft window */
		const int ll_max_rows = 26;


		/* Actual size of UpperLeft window */
		int ul_rows = MAX(ul_min_rows, LINES - (ll_max_rows + 1));
		int ul_cols = MAX(ul_min_cols, COLS - (ur_max_cols + 1));



		/* Create several terms */
		for (i = 0; i < num_term; i++)
		{
			int rows, cols, y, x;

			/* Decide on size and position */
			switch (i)
			{
				/* Upper left */
				case 0:
				{
					rows = ul_rows;
					cols = ul_cols;
					y = x = 0;
					break;
				}

				/* Lower left */
				case 1:
				{
					rows = LINES - (ul_rows + 1);
					cols = ul_cols;
					y = ul_rows + 1;
					x = 0;
					break;
				}

				/* Upper right */
				case 2:
				{
					rows = ul_rows;
					cols = COLS - (ul_cols + 1);
					y = 0;
					x = ul_cols + 1;
					break;
				}

				/* Lower right */
				case 3:
				{
					rows = LINES - (ul_rows + 1);
					cols = COLS - (ul_cols + 1);
					y = ul_rows + 1;
					x = ul_cols + 1;
					break;
				}

				/* XXX */
				default:
				{
					rows = cols = y = x = 0;
					break;
				}
			}

			/* Skip non-existant windows */
			if (rows <= 0 || cols <= 0) continue;

			/* Create a term */
			term_data_init_gcu(&data[next_win], rows, cols, y, x);

			/* Remember the term */
			angband_term[next_win] = &data[next_win].t;

			/* One more window */
			next_win++;
		}
	}

	/* Activate the "Angband" window screen */
	Term_activate(&data[0].t);

	/* Remember the active screen */
	term_screen = &data[0].t;

	/* Success */
	return (0);
}


#endif /* USE_GCU */
Code:

Gwarl is offline   Reply With Quote
Old October 9, 2017, 14:00   #10
Quirk
Apprentice
 
Join Date: Mar 2016
Posts: 54
Quirk is on a distinguished road
Quote:
Originally Posted by Gwarl View Post
Okay this is up on angband.live now.

Here's the patched main-gcu.c so support 256-color terminals:
Ugh. I was going to say something mildly upset about the way can_fix_color is still in there but now untouched by anything, but in the Sil codebase it was only set within an #ifdef and depended on a can_change_color() function that no longer exists in Sil...

I'm going to clean this file up a little bit on top of applying the patch, though if I start letting myself get generally annoyed by dead code and warnings progress will grind to a halt. I've already spent a bunch of time tracking down memory corruption. I guess when an old C codebase has had twenty years of evolution these things happen.
Quirk is offline   Reply With Quote
Reply


Currently Active Users Viewing This Thread: 2 (1 members and 1 guests)
Bucephalus
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
YASD: saving in bad state Pete Mack AAR 3 June 15, 2017 07:04
The state of things Apostlyte Vanilla 24 June 6, 2017 11:05
v4 update Magnate v4 10 December 13, 2011 13:40
State of Angband master branch d_m Development 80 November 26, 2010 14:14
State of code ewert Development 2 August 4, 2010 15:08


All times are GMT +1. The time now is 04:31.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2017, vBulletin Solutions, Inc.