tReplace lots of nasty "magic" numbers when printing to the prompt line or user… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit b23da53b00549c97cfb60fb8bcea0eee0ec06ef4 | |
parent 7c08b5b23e28bd8a8f0a9f298b4196a4cd0acd34 | |
Author: Ben Webb <[email protected]> | |
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(-) | |
--- | |
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 | |
diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_clien… | |
t@@ -1,4 +1,5 @@ | |
/************************************************************************ | |
+ * | |
* curses_client.c dopewars client using the (n)curses console library * | |
* Copyright (C) 1998-2003 Ben Webb * | |
* Email: [email protected] * | |
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,… | |
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,… | |
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,… | |
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, G… | |
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, cha… | |
{ | |
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… | |
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); |