tReplace lots of nasty "magic" numbers when printing to the prompt line or user interface area in the curses client with functions; provide a general function display_select_list that displays a list of strings in columns (e.g. for drugs, guns, logged on players, or locations to jet to). - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit b23da53b00549c97cfb60fb8bcea0eee0ec06ef4
(DIR) parent 7c08b5b23e28bd8a8f0a9f298b4196a4cd0acd34
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Mon, 20 Jan 2003 13:04:52 +0000
Replace lots of nasty "magic" numbers when printing to the prompt line or
user interface area in the curses client with functions; provide a general
function display_select_list that displays a list of strings in columns
(e.g. for drugs, guns, logged on players, or locations to jet to).
Diffstat:
M ChangeLog | 2 ++
M src/curses_client/curses_client.c | 415 +++++++++++++++++++------------
2 files changed, 254 insertions(+), 163 deletions(-)
---
(DIR) diff --git a/ChangeLog b/ChangeLog
t@@ -1,6 +1,8 @@
cvs
- The messages window in the curses client can now be scrolled with the
+ and - keys
+ - The curses client now makes better use of space with screen sizes
+ larger than 80x24
1.5.8 21-10-2002
- Options dialog now allows sounds for all supported game events to be set
(DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c
t@@ -1,4 +1,5 @@
/************************************************************************
+ *
* curses_client.c dopewars client using the (n)curses console library *
* Copyright (C) 1998-2003 Ben Webb *
* Email: ben@bellatrix.pcl.ox.ac.uk *
t@@ -150,6 +151,37 @@ void ResizeHandle(int sig)
ResizedFlag = 1;
}
+/*
+ * Returns the topmost row of the message area
+ */
+static int get_msg_area_top(void)
+{
+ return 10;
+}
+
+/*
+ * Returns the bottommost row of the message area
+ */
+static int get_msg_area_bottom(void)
+{
+ return 14;
+}
+
+static int get_ui_area_top(void)
+{
+ return 16;
+}
+
+static int get_ui_area_bottom(void)
+{
+ return Depth;
+}
+
+static int get_prompt_line(void)
+{
+ return Depth - 2;
+}
+
/*
* Checks to see if the curses window needs to be resized - i.e. if a
* SIGWINCH signal has been received.
t@@ -195,7 +227,7 @@ static void mvaddcentstr(const int row, const gchar *str)
guint col, len;
len = strlen(str);
- col = (len > Width ? 0 : (Width - len) / 2);
+ col = (len > (guint)Width ? 0 : ((guint)Width - len) / 2);
mvaddstr(row, col, str);
}
t@@ -286,20 +318,21 @@ void display_intro(void)
static void SelectServerManually(void)
{
gchar *text, *PortText;
+ int top = get_ui_area_top();
if (ServerName[0] == '(')
AssignName(&ServerName, "localhost");
attrset(TextAttr);
clear_bottom();
- mvaddstr(17, 1,
+ mvaddstr(top + 1, 1,
/* Prompts for hostname and port when selecting a server
* manually */
_("Please enter the hostname and port of a dopewars server:-"));
- text = nice_input(_("Hostname: "), 18, 1, FALSE, ServerName, '\0');
+ text = nice_input(_("Hostname: "), top + 2, 1, FALSE, ServerName, '\0');
AssignName(&ServerName, text);
g_free(text);
PortText = g_strdup_printf("%d", Port);
- text = nice_input(_("Port: "), 19, 1, TRUE, PortText, '\0');
+ text = nice_input(_("Port: "), top + 3, 1, TRUE, PortText, '\0');
Port = atoi(text);
g_free(text);
g_free(PortText);
t@@ -322,10 +355,11 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
int maxsock;
gboolean DoneOK;
HttpConnection *MetaConn;
+ int top = get_ui_area_top();
attrset(TextAttr);
clear_bottom();
- mvaddstr(17, 1, _("Please wait... attempting to contact metaserver..."));
+ mvaddstr(top + 1, 1, _("Please wait... attempting to contact metaserver..."));
refresh();
if (OpenMetaHttpConnection(&MetaConn)) {
t@@ -384,11 +418,11 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
clear_bottom();
/* Printout of metaserver information in curses client */
g_string_sprintf(text, _("Server : %s"), ThisServer->Name);
- mvaddstr(17, 1, text->str);
+ mvaddstr(top + 1, 1, text->str);
g_string_sprintf(text, _("Port : %d"), ThisServer->Port);
- mvaddstr(18, 1, text->str);
+ mvaddstr(top + 2, 1, text->str);
g_string_sprintf(text, _("Version : %s"), ThisServer->Version);
- mvaddstr(18, 40, text->str);
+ mvaddstr(top + 2, 40, text->str);
if (ThisServer->CurPlayers == -1) {
g_string_sprintf(text, _("Players: -unknown- (maximum %d)"),
ThisServer->MaxPlayers);
t@@ -396,13 +430,13 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
g_string_sprintf(text, _("Players: %d (maximum %d)"),
ThisServer->CurPlayers, ThisServer->MaxPlayers);
}
- mvaddstr(19, 1, text->str);
+ mvaddstr(top + 3, 1, text->str);
g_string_sprintf(text, _("Up since : %s"), ThisServer->UpSince);
- mvaddstr(19, 40, text->str);
+ mvaddstr(top + 3, 40, text->str);
g_string_sprintf(text, _("Comment: %s"), ThisServer->Comment);
- mvaddstr(20, 1, text->str);
+ mvaddstr(top + 4, 1, text->str);
attrset(PromptAttr);
- mvaddstr(23, 1,
+ mvaddstr(get_prompt_line() + 1, 1,
_("N>ext server; P>revious server; S>elect this server... "));
/* The three keys that are valid responses to the previous question -
t@@ -434,7 +468,7 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
g_string_assign(errstr, "No servers listed on metaserver");
return FALSE;
}
- clear_line(17);
+ clear_line(top + 1);
refresh();
g_string_free(text, TRUE);
return TRUE;
t@@ -594,7 +628,7 @@ static gboolean ConnectToServer(Player *Play)
gboolean MetaOK = TRUE, NetOK = TRUE, firstrun = FALSE;
GString *errstr;
gchar *text;
- int c;
+ int c, top = get_ui_area_top();
errstr = g_string_new("");
t@@ -617,41 +651,41 @@ static gboolean ConnectToServer(Player *Play)
attrset(TextAttr);
clear_bottom();
if (MetaOK && !firstrun) {
- mvaddstr(17, 1, _("Please wait... attempting to contact "
- "dopewars server..."));
+ mvaddstr(top + 1, 1, _("Please wait... attempting to contact "
+ "dopewars server..."));
refresh();
NetOK = DoConnect(Play, errstr);
}
if (!NetOK || !MetaOK || firstrun) {
firstrun = FALSE;
- clear_line(16);
- clear_line(17);
+ clear_line(top);
+ clear_line(top + 1);
if (!MetaOK) {
/* Display of an error while contacting the metaserver */
- mvaddstr(16, 1, _("Cannot get metaserver details"));
+ mvaddstr(top, 1, _("Cannot get metaserver details"));
text = g_strdup_printf(" (%s)", errstr->str);
- mvaddstr(17, 1, text);
+ mvaddstr(top + 1, 1, text);
g_free(text);
} else if (!NetOK) {
/* Display of an error message while trying to contact a dopewars
* server (the error message itself is displayed on the next
* screen line) */
- mvaddstr(16, 1, _("Could not start multiplayer dopewars"));
+ mvaddstr(top, 1, _("Could not start multiplayer dopewars"));
text = g_strdup_printf(" (%s)", errstr->str);
- mvaddstr(17, 1, text);
+ mvaddstr(top + 1, 1, text);
g_free(text);
}
MetaOK = NetOK = TRUE;
attrset(PromptAttr);
- mvaddstr(18, 1,
+ mvaddstr(top + 2, 1,
_("Will you... C>onnect to a named dopewars server"));
- mvaddstr(19, 1,
+ mvaddstr(top + 3, 1,
_(" L>ist the servers on the metaserver, and "
"select one"));
- mvaddstr(20, 1,
+ mvaddstr(top + 4, 1,
_(" Q>uit (where you can start a server "
"by typing \"dopewars -s\")"));
- mvaddstr(21, 1, _(" or P>lay single-player ? "));
+ mvaddstr(top + 5, 1, _(" or P>lay single-player ? "));
attrset(TextAttr);
/* Translate these 4 keys in line with the above options, keeping
t@@ -680,6 +714,52 @@ static gboolean ConnectToServer(Player *Play)
}
#endif /* NETWORKING */
+/*
+ * Displays the list of null-terminated names given by the "names"
+ * parameter in the bottom part of the screen. The names are spaced
+ * in columns so as to attempt to make best use of the available space.
+ * After displaying the names, the list is freed.
+ */
+void display_select_list(GSList *names)
+{
+ int top = get_ui_area_top() + 1, maxrows;
+ guint maxlen = 0;
+ int numcols, numrows, xoff, count, numlist;
+ GSList *listpt;
+
+ maxrows = get_prompt_line() - top;
+
+ for (listpt = names, numlist = 0; listpt;
+ listpt = g_slist_next(listpt), numlist++) {
+ maxlen = MAX(maxlen, strlen(listpt->data));
+ }
+
+ maxlen += 3;
+ numcols = Width / maxlen;
+ numcols = MAX(numcols, 1);
+
+ /* Try and make the list reasonably "square" */
+ while(numcols > 1) {
+ numrows = (numlist + numcols - 2) / (numcols - 1);
+ if (numrows <= maxrows && numrows <= numcols && numcols > 1) {
+ numcols--;
+ } else {
+ break;
+ }
+ }
+
+ xoff = (Width - numcols * maxlen + 3) / 2;
+ xoff = MAX(xoff, 0);
+
+ count = 0;
+ for (listpt = names; listpt; listpt = g_slist_next(listpt), count++) {
+ mvaddstr(top + count / numcols, xoff + maxlen * (count % numcols),
+ listpt->data);
+ g_free(listpt->data);
+ }
+ g_slist_free(names);
+}
+
/*
* Displays the list of locations and prompts the user to select one.
* If "AllowReturn" is TRUE, then if the current location is selected
t@@ -694,32 +774,35 @@ static gboolean ConnectToServer(Player *Play)
static gboolean jet(Player *Play, gboolean AllowReturn)
{
int i, c;
- GString *text;
+ GSList *names = NULL;
+ GString *str;
- text = g_string_new("");
+ str = g_string_new("");
attrset(TextAttr);
clear_bottom();
for (i = 0; i < NumLocation; i++) {
+ gchar *text;
/* Display of shortcut keys and locations to jet to */
- dpg_string_sprintf(text, _("%d. %tde"), i + 1, Location[i].Name);
- mvaddstr(17 + i / 3, (i % 3) * 20 + 12, text->str);
+ text = dpg_strdup_printf(_("%d. %tde"), i + 1, Location[i].Name);
+ names = g_slist_append(names, text);
}
+ display_select_list(names);
attrset(PromptAttr);
/* Prompt when the player chooses to "jet" to a new location */
- mvaddstr(22, 22, _("Where to, dude ? "));
+ mvaddstr(get_prompt_line(), 22, _("Where to, dude ? "));
attrset(TextAttr);
curs_set(1);
do {
c = bgetch();
if (c >= '1' && c < '1' + NumLocation) {
- dpg_string_sprintf(text, _("%/Location display/%tde"),
+ dpg_string_sprintf(str, _("%/Location display/%tde"),
Location[c - '1'].Name);
- addstr(text->str);
+ addstr(str->str);
if (Play->IsAt != c - '1') {
- g_string_sprintf(text, "%d", c - '1');
+ g_string_sprintf(str, "%d", c - '1');
DisplayMode = DM_NONE;
- SendClientMessage(Play, C_NONE, C_REQUESTJET, NULL, text->str);
+ SendClientMessage(Play, C_NONE, C_REQUESTJET, NULL, str->str);
} else {
c = 0;
}
t@@ -729,7 +812,7 @@ static gboolean jet(Player *Play, gboolean AllowReturn)
} while (c == 0 && !AllowReturn);
curs_set(0);
- g_string_free(text, TRUE);
+ g_string_free(str, TRUE);
return (c != 0);
}
t@@ -739,7 +822,7 @@ static gboolean jet(Player *Play, gboolean AllowReturn)
*/
static void DropDrugs(Player *Play)
{
- int i, c, num, NumDrugs;
+ int i, c, num, NumDrugs, top = get_ui_area_top();
GString *text;
gchar *buf;
t@@ -751,18 +834,18 @@ static void DropDrugs(Player *Play)
* default) */
_("You can\'t get any cash for the following "
"carried %tde :"), Names.Drugs);
- mvaddstr(16, 1, text->str);
+ mvaddstr(top, 1, text->str);
NumDrugs = 0;
for (i = 0; i < NumDrug; i++) {
if (Play->Drugs[i].Carried > 0 && Play->Drugs[i].Price == 0) {
g_string_sprintf(text, "%c. %-10s %-8d", NumDrugs + 'A',
Drug[i].Name, Play->Drugs[i].Carried);
- mvaddstr(17 + NumDrugs / 3, (NumDrugs % 3) * 25 + 4, text->str);
+ mvaddstr(top + NumDrugs / 3, (NumDrugs % 3) * 25 + 4, text->str);
NumDrugs++;
}
}
attrset(PromptAttr);
- mvaddstr(22, 20, _("What do you want to drop? "));
+ mvaddstr(get_prompt_line(), 20, _("What do you want to drop? "));
curs_set(1);
attrset(TextAttr);
c = bgetch();
t@@ -772,9 +855,8 @@ static void DropDrugs(Player *Play)
c--;
if (c < 'A') {
addstr(Drug[i].Name);
- buf =
- nice_input(_("How many do you drop? "), 23, 8, TRUE, NULL,
- '\0');
+ buf = nice_input(_("How many do you drop? "), get_prompt_line() + 1,
+ 8, TRUE, NULL, '\0');
num = atoi(buf);
g_free(buf);
if (num > 0) {
t@@ -805,13 +887,13 @@ static void DealDrugs(Player *Play, gboolean Buy)
if (Play->Drugs[c].Price > 0)
NumDrugsHere++;
- clear_line(22);
+ clear_line(get_prompt_line());
attrset(PromptAttr);
if (Buy) {
/* Buy and sell prompts for dealing drugs or guns */
- mvaddstr(22, 20, _("What do you wish to buy? "));
+ mvaddstr(get_prompt_line(), 20, _("What do you wish to buy? "));
} else {
- mvaddstr(22, 20, _("What do you wish to sell? "));
+ mvaddstr(get_prompt_line(), 20, _("What do you wish to sell? "));
}
curs_set(1);
attrset(TextAttr);
t@@ -831,9 +913,9 @@ static void DealDrugs(Player *Play, gboolean Buy)
* buying drugs */
text = g_strdup_printf(_("You can afford %d, and can carry %d. "),
CanAfford, CanCarry);
- mvaddstr(23, 2, text);
- input = nice_input(_("How many do you buy? "), 23, 2 + strlen(text),
- TRUE, NULL, '\0');
+ mvaddstr(get_prompt_line() + 1, 2, text);
+ input = nice_input(_("How many do you buy? "), get_prompt_line() + 1,
+ 2 + strlen(text), TRUE, NULL, '\0');
c = atoi(input);
g_free(input);
g_free(text);
t@@ -847,9 +929,9 @@ static void DealDrugs(Player *Play, gboolean Buy)
text =
g_strdup_printf(_("You have %d. "),
Play->Drugs[DrugNum].Carried);
- mvaddstr(23, 2, text);
- input = nice_input(_("How many do you sell? "), 23, 2 + strlen(text),
- TRUE, NULL, '\0');
+ mvaddstr(get_prompt_line() + 1, 2, text);
+ input = nice_input(_("How many do you sell? "), get_prompt_line() + 1,
+ 2 + strlen(text), TRUE, NULL, '\0');
c = atoi(input);
g_free(input);
g_free(text);
t@@ -876,7 +958,7 @@ static void GiveErrand(Player *Play)
text = g_string_new("");
attrset(TextAttr);
clear_bottom();
- y = 17;
+ y = get_ui_area_top() + 1;
/* Prompt for sending your bitches out to spy etc. (%tde = "bitches" by
* default) */
t@@ -948,9 +1030,9 @@ static void GiveErrand(Player *Play)
static int want_to_quit(void)
{
attrset(TextAttr);
- clear_line(22);
+ clear_line(get_prompt_line());
attrset(PromptAttr);
- mvaddstr(22, 1, _("Are you sure you want to quit? "));
+ mvaddstr(get_prompt_line(), 1, _("Are you sure you want to quit? "));
attrset(TextAttr);
return (GetKey(_("YN"), "YN", FALSE, TRUE, FALSE) != 'N');
}
t@@ -963,7 +1045,8 @@ static void change_name(Player *Play, gboolean nullname)
gchar *NewName;
/* Prompt for player to change his/her name */
- NewName = nice_input(_("New name: "), 23, 0, FALSE, NULL, '\0');
+ NewName = nice_input(_("New name: "), get_prompt_line() + 1, 0, FALSE,
+ NULL, '\0');
if (NewName[0]) {
StripTerminators(NewName);
t@@ -1028,17 +1111,17 @@ void HandleClientMessage(char *Message, Player *Play)
break;
case C_PUSH:
attrset(TextAttr);
- clear_line(22);
- mvaddstr(22, 0, _("You have been pushed from the server. "
- "Reverting to single player mode."));
+ clear_line(get_prompt_line());
+ mvaddstr(get_prompt_line(), 0, _("You have been pushed from the server. "
+ "Reverting to single player mode."));
nice_wait();
SwitchToSinglePlayer(Play);
print_status(Play, TRUE);
break;
case C_QUIT:
attrset(TextAttr);
- clear_line(22);
- mvaddstr(22, 0,
+ clear_line(get_prompt_line());
+ mvaddstr(get_prompt_line(), 0,
_("The server has terminated. Reverting to "
"single player mode."));
nice_wait();
t@@ -1077,7 +1160,7 @@ void HandleClientMessage(char *Message, Player *Play)
text = g_strdup_printf(_("%s will now be known as %s."),
GetPlayerName(From), Data);
SetPlayerName(From, Data);
- mvaddstr(22, 0, text);
+ mvaddstr(get_prompt_line(), 0, text);
g_free(text);
nice_wait();
break;
t@@ -1141,18 +1224,19 @@ void HandleClientMessage(char *Message, Player *Play)
}
break;
case C_NEWNAME:
- clear_line(22);
- clear_line(23);
+ clear_line(get_prompt_line());
+ clear_line(get_prompt_line() + 1);
attrset(TextAttr);
- mvaddstr(22, 0, _("Unfortunately, somebody else is already "
- "using \"your\" name. Please change it."));
+ mvaddstr(get_prompt_line(), 0,
+ _("Unfortunately, somebody else is already "
+ "using \"your\" name. Please change it."));
change_name(Play, TRUE);
break;
default:
if (!Handled) {
text = g_strdup_printf("%s^%c^%s^%s", GetPlayerName(From), Code,
GetPlayerName(Play), Data);
- mvaddstr(22, 0, text);
+ mvaddstr(get_prompt_line(), 0, text);
g_free(text);
nice_wait();
}
t@@ -1208,14 +1292,14 @@ void PrintMessage(const gchar *text)
guint i, line;
attrset(TextAttr);
- clear_line(16);
+ clear_line(get_ui_area_top());
line = 1;
for (i = 0; i < strlen(text) && (text[i] == '^' || text[i] == '\n'); i++)
line++;
clear_exceptfor(line);
- line = 17;
+ line = get_ui_area_top() + 1;
move(line, 1);
for (i = 0; i < strlen(text); i++) {
if (text[i] == '^' || text[i] == '\n') {
t@@ -1231,19 +1315,19 @@ static void SellGun(Player *Play)
gchar *text;
gint gunind;
- clear_line(22);
+ clear_line(get_prompt_line());
if (TotalGunsCarried(Play) == 0) {
/* Error - player tried to sell guns that he/she doesn't have
* (%tde="guns" by default) */
text = dpg_strdup_printf(_("You don't have any %tde to sell!"),
Names.Guns);
- mvaddstr(22, (Width - strlen(text)) / 2, text);
+ mvaddcentstr(get_prompt_line(), text);
g_free(text);
nice_wait();
- clear_line(23);
+ clear_line(get_prompt_line() + 1);
} else {
attrset(PromptAttr);
- mvaddstr(22, 20, _("What do you wish to sell? "));
+ mvaddstr(get_prompt_line(), 20, _("What do you wish to sell? "));
curs_set(1);
attrset(TextAttr);
gunind = bgetch();
t@@ -1252,11 +1336,11 @@ static void SellGun(Player *Play)
gunind -= 'A';
addstr(Gun[gunind].Name);
if (Play->Guns[gunind].Carried == 0) {
- clear_line(22);
+ clear_line(get_prompt_line());
/* Error - player tried to sell some guns that he/she doesn't have */
- mvaddstr(22, 10, _("You don't have any to sell!"));
+ mvaddstr(get_prompt_line(), 10, _("You don't have any to sell!"));
nice_wait();
- clear_line(23);
+ clear_line(get_prompt_line() + 1);
} else {
Play->Cash += Gun[gunind].Price;
Play->CoatSize += Gun[gunind].Space;
t@@ -1275,7 +1359,7 @@ static void BuyGun(Player *Play)
gchar *text;
gint gunind;
- clear_line(22);
+ clear_line(get_prompt_line());
if (TotalGunsCarried(Play) >= Play->Bitches.Carried + 2) {
text = dpg_strdup_printf(
/* Error - player tried to buy more guns
t@@ -1285,13 +1369,13 @@ static void BuyGun(Player *Play)
_("You'll need more %tde to carry "
"any more %tde!"),
Names.Bitches, Names.Guns);
- mvaddstr(22, (Width - strlen(text)) / 2, text);
+ mvaddcentstr(get_prompt_line(), text);
g_free(text);
nice_wait();
- clear_line(23);
+ clear_line(get_prompt_line() + 1);
} else {
attrset(PromptAttr);
- mvaddstr(22, 20, _("What do you wish to buy? "));
+ mvaddstr(get_prompt_line(), 20, _("What do you wish to buy? "));
curs_set(1);
attrset(TextAttr);
gunind = bgetch();
t@@ -1300,25 +1384,25 @@ static void BuyGun(Player *Play)
gunind -= 'A';
addstr(Gun[gunind].Name);
if (Gun[gunind].Space > Play->CoatSize) {
- clear_line(22);
+ clear_line(get_prompt_line());
/* Error - player tried to buy a gun that he/she doesn't have
* space for (%tde="gun" by default) */
text = dpg_strdup_printf(_("You don't have enough space to "
"carry that %tde!"), Names.Gun);
- mvaddstr(22, (Width - strlen(text)) / 2, text);
+ mvaddcentstr(get_prompt_line(), text);
g_free(text);
nice_wait();
- clear_line(23);
+ clear_line(get_prompt_line() + 1);
} else if (Gun[gunind].Price > Play->Cash) {
- clear_line(22);
+ clear_line(get_prompt_line());
/* Error - player tried to buy a gun that he/she can't afford
* (%tde="gun" by default) */
text = dpg_strdup_printf(_("You don't have enough cash to buy "
"that %tde!"), Names.Gun);
- mvaddstr(22, (Width - strlen(text)) / 2, text);
+ mvaddcentstr(get_prompt_line(), text);
g_free(text);
nice_wait();
- clear_line(23);
+ clear_line(get_prompt_line() + 1);
} else {
Play->Cash -= Gun[gunind].Price;
Play->CoatSize -= Gun[gunind].Space;
t@@ -1339,24 +1423,24 @@ static void BuyGun(Player *Play)
void GunShop(Player *Play)
{
int i, action;
+ GSList *names = NULL;
gchar *text;
print_status(Play, FALSE);
attrset(TextAttr);
clear_bottom();
for (i = 0; i < NumGun; i++) {
- text =
- dpg_strdup_printf("%c. %-22tde %12P", 'A' + i, Gun[i].Name,
- Gun[i].Price);
- mvaddstr(17 + i / 2, (i % 2) * 40 + 1, text);
- g_free(text);
+ text = dpg_strdup_printf("%c. %-22tde %12P", 'A' + i, Gun[i].Name,
+ Gun[i].Price);
+ names = g_slist_append(names, text);
}
+ display_select_list(names);
do {
/* Prompt for actions in the gun shop */
text = _("Will you B>uy, S>ell, or L>eave? ");
attrset(PromptAttr);
- clear_line(22);
- mvaddcentstr(22, text);
+ clear_line(get_prompt_line());
+ mvaddcentstr(get_prompt_line(), text);
attrset(TextAttr);
/* Translate these three keys in line with the above options, keeping
t@@ -1552,38 +1636,41 @@ void clear_line(int line)
}
/*
- * Clears the bottom of the screen (i.e. from line 16 to line 23)
+ * Clears the bottom of the screen (the user interface)
* except for the top "skip" lines.
*/
void clear_exceptfor(int skip)
{
- int i;
+ int i, from = get_ui_area_top() + skip, to = get_ui_area_bottom();
- for (i = 16 + skip; i <= 23; i++)
+ for (i = from; i <= to; i++) {
clear_line(i);
+ }
}
/*
- * Clears screen lines 16 to 23.
+ * Clears the bottom part of the screen (the user interface)
*/
void clear_bottom(void)
{
- int i;
+ int i, from = get_ui_area_top(), to = get_ui_area_bottom();
- for (i = 16; i <= 23; i++)
+ for (i = from; i <= to; i++) {
clear_line(i);
+ }
}
/*
- * Clears the entire screen; 24 lines of 80 characters each.
+ * Clears the entire screen
*/
void clear_screen(void)
{
int i;
- for (i = 0; i < Depth; i++)
+ for (i = 0; i < Depth; i++) {
clear_line(i);
+ }
}
/*
t@@ -1593,7 +1680,7 @@ void clear_screen(void)
void nice_wait()
{
attrset(PromptAttr);
- mvaddcentstr(23, _("Press any key..."));
+ mvaddcentstr(get_prompt_line() + 1, _("Press any key..."));
bgetch();
attrset(TextAttr);
}
t@@ -1655,22 +1742,6 @@ void DisplayFightMessage(Player *Play, char *text)
}
}
-/*
- * Returns the topmost row of the message area
- */
-static int get_msg_area_top(void)
-{
- return 10;
-}
-
-/*
- * Returns the bottommost row of the message area
- */
-static int get_msg_area_bottom(void)
-{
- return 14;
-}
-
/* Number of lines that the message window is scrolled back by */
static int scrollpos = 0;
t@@ -2017,37 +2088,39 @@ Player *ListPlayers(Player *Play, gboolean Select, char *Prompt)
{
Player *tmp = NULL;
GSList *list;
- int i, c;
+ int i, c, top = get_ui_area_top(), bottom = get_ui_area_bottom();
gchar *text;
+ GSList *names = NULL;
attrset(TextAttr);
clear_bottom();
if (!FirstClient || (!g_slist_next(FirstClient) &&
FirstClient->data == Play)) {
text = _("No other players are currently logged on!");
- mvaddstr(18, (Width - strlen(text)) / 2, text);
+ mvaddcentstr((top + bottom) / 2, text);
nice_wait();
return 0;
}
- mvaddstr(16, 1, _("Players currently logged on:-"));
+ mvaddstr(top, 1, _("Players currently logged on:-"));
i = 0;
for (list = FirstClient; list; list = g_slist_next(list)) {
tmp = (Player *)list->data;
if (strcmp(GetPlayerName(tmp), GetPlayerName(Play)) == 0)
continue;
- if (Select)
+ if (Select) {
text = g_strdup_printf("%c. %s", 'A' + i, GetPlayerName(tmp));
- else
+ } else {
text = g_strdup(GetPlayerName(tmp));
- mvaddstr(17 + i / 2, (i % 2) * 40 + 1, text);
- g_free(text);
+ }
+ names = g_slist_append(names, text);
i++;
}
+ display_select_list(names);
if (Prompt) {
attrset(PromptAttr);
- mvaddstr(22, 10, Prompt);
+ mvaddstr(get_prompt_line(), 10, Prompt);
attrset(TextAttr);
}
if (Select) {
t@@ -2163,6 +2236,38 @@ char *nice_input(char *prompt, int sy, int sx, gboolean digitsonly,
return ReturnString;
}
+static void DisplayDrugsHere(Player *Play)
+{
+ int NumDrugsHere, i, c;
+ gchar *text;
+ GSList *names = NULL;
+
+ attrset(TextAttr);
+ NumDrugsHere = 0;
+ for (i = 0; i < NumDrug; i++) {
+ if (Play->Drugs[i].Price > 0) {
+ NumDrugsHere++;
+ }
+ }
+ clear_bottom();
+ /* Display of drug prices (%tde="drugs" by default) */
+ text = dpg_strdup_printf(_("Hey dude, the prices of %tde here are:"),
+ Names.Drugs);
+ mvaddstr(get_ui_area_top(), 1, text);
+ g_free(text);
+ for (c = 0, i = GetNextDrugIndex(-1, Play);
+ c < NumDrugsHere && i != -1;
+ c++, i = GetNextDrugIndex(i, Play)) {
+ /* List of individual drug names for selection (%tde="Opium" etc.
+ * by default) */
+ text = dpg_strdup_printf( _("%c. %-10tde %8P"), 'A' + c,
+ Drug[i].Name, Play->Drugs[i].Price);
+ names = g_slist_append(names, text);
+ }
+ display_select_list(names);
+ attrset(PromptAttr);
+}
+
/*
* Loop which handles the user playing an interactive game (i.e. "Play"
* is a client connected to a server, either locally or remotely)
t@@ -2186,7 +2291,6 @@ static void Curses_DoGame(Player *Play)
gchar *pt;
gboolean justconnected = FALSE;
#endif
- int NumDrugsHere;
int MaxSock;
char HaveWorthless;
Player *tmp;
t@@ -2214,9 +2318,8 @@ static void Curses_DoGame(Player *Play)
buf = NULL;
do {
g_free(buf);
- buf =
- nice_input(_("Hey dude, what's your name? "), 17, 1, FALSE,
- OldName, '\0');
+ buf = nice_input(_("Hey dude, what's your name? "), get_ui_area_top() + 1,
+ 1, FALSE, OldName, '\0');
} while (buf[0] == 0);
#if NETWORKING
if (WantNetwork) {
t@@ -2249,32 +2352,14 @@ static void Curses_DoGame(Player *Play)
for (i = 0; i < NumDrug; i++) {
if (Play->Drugs[i].Carried > 0) {
IsCarrying = 1;
- if (Play->Drugs[i].Price == 0)
+ if (Play->Drugs[i].Price == 0) {
HaveWorthless = 1;
+ }
}
}
switch (DisplayMode) {
case DM_STREET:
- attrset(TextAttr);
- NumDrugsHere = 0;
- for (i = 0; i < NumDrug; i++)
- if (Play->Drugs[i].Price > 0)
- NumDrugsHere++;
- clear_bottom();
- /* Display of drug prices (%tde="drugs" by default) */
- dpg_string_sprintf(text, _("Hey dude, the prices of %tde here are:"),
- Names.Drugs);
- mvaddstr(16, 1, text->str);
- for (c = 0, i = GetNextDrugIndex(-1, Play);
- c < NumDrugsHere && i != -1;
- c++, i = GetNextDrugIndex(i, Play)) {
- /* List of individual drug names for selection (%tde="Opium" etc.
- * by default) */
- dpg_string_sprintf(text, _("%c. %-10tde %8P"), 'A' + c,
- Drug[i].Name, Play->Drugs[i].Price);
- mvaddstr(17 + c / 3, (c % 3) * 25 + 4, text->str);
- }
- attrset(PromptAttr);
+ DisplayDrugsHere(Play);
/* Prompts for "normal" actions in curses client */
g_string_assign(text, _("Will you B>uy"));
if (IsCarrying)
t@@ -2294,7 +2379,7 @@ static void Curses_DoGame(Player *Play)
g_string_append(text, _(", J>et"));
}
g_string_append(text, _(", or Q>uit? "));
- mvaddcentstr(22, text->str);
+ mvaddcentstr(get_prompt_line(), text->str);
attrset(TextAttr);
curs_set(1);
break;
t@@ -2316,7 +2401,7 @@ static void Curses_DoGame(Player *Play)
/* (%tde = "drugs" by default here) */
dpg_string_sprintfa(text, _("D>eal %tde, "), Names.Drugs);
g_string_append(text, _("or Q>uit? "));
- mvaddcentstr(22, text->str);
+ mvaddcentstr(get_prompt_line(), text->str);
attrset(TextAttr);
curs_set(1);
break;
t@@ -2329,7 +2414,7 @@ static void Curses_DoGame(Player *Play)
g_string_append(text, Names.Drugs);
g_string_append(text, ", or Q>uit? ");
attrset(PromptAttr);
- mvaddcentstr(22, text->str);
+ mvaddcentstr(get_prompt_line(), text->str);
attrset(TextAttr);
curs_set(1);
break;
t@@ -2378,9 +2463,10 @@ static void Curses_DoGame(Player *Play)
}
if (!DoneOK) {
attrset(TextAttr);
- clear_line(22);
- mvaddstr(22, 0, _("Connection to server lost! "
- "Reverting to single player mode"));
+ clear_line(get_prompt_line());
+ mvaddstr(get_prompt_line(), 0,
+ _("Connection to server lost! "
+ "Reverting to single player mode"));
nice_wait();
SwitchToSinglePlayer(Play);
print_status(Play, TRUE);
t@@ -2441,7 +2527,8 @@ static void Curses_DoGame(Player *Play)
} else if (c == 'L') {
if (Network) {
attrset(PromptAttr);
- mvaddstr(23, 20, _("List what? P>layers or S>cores? "));
+ mvaddstr(get_prompt_line() + 1, 20,
+ _("List what? P>layers or S>cores? "));
/* P>layers, S>cores */
i = GetKey(_("PS"), "PS", TRUE, FALSE, FALSE);
if (i == 'P') {
t@@ -2460,9 +2547,10 @@ static void Curses_DoGame(Player *Play)
"(talk privately to) ? "));
if (tmp) {
attrset(TextAttr);
- clear_line(22);
+ clear_line(get_prompt_line());
/* Prompt for sending player-player messages */
- TalkMsg = nice_input(_("Talk: "), 22, 0, FALSE, NULL, '\0');
+ TalkMsg = nice_input(_("Talk: "), get_prompt_line(), 0, FALSE,
+ NULL, '\0');
if (TalkMsg[0]) {
SendClientMessage(Play, C_NONE, C_MSGTO, tmp, TalkMsg);
buf = g_strdup_printf("%s->%s: %s", GetPlayerName(Play),
t@@ -2474,8 +2562,9 @@ static void Curses_DoGame(Player *Play)
}
} else if (c == 'T' && Client) {
attrset(TextAttr);
- clear_line(22);
- TalkMsg = nice_input(_("Talk: "), 22, 0, FALSE, NULL, '\0');
+ clear_line(get_prompt_line());
+ TalkMsg = nice_input(_("Talk: "), get_prompt_line(), 0,
+ FALSE, NULL, '\0');
if (TalkMsg[0]) {
SendClientMessage(Play, C_NONE, C_MSG, NULL, TalkMsg);
buf = g_strdup_printf("%s: %s", GetPlayerName(Play), TalkMsg);
t@@ -2587,7 +2676,7 @@ void CursesLoop(struct CMDLINE *cmdline)
CleanUpServer();
RestoreConfig();
attrset(TextAttr);
- mvaddstr(23, 20, _("Play again? "));
+ mvaddstr(get_prompt_line() + 1, 20, _("Play again? "));
c = GetKey(_("YN"), "YN", TRUE, TRUE, FALSE);
} while (c == 'Y');
FirstClient = RemovePlayer(Play, FirstClient);