(svn r1215) Feature: You can now make a custom currency by chosing "Custom..."
authordominik
Wed, 22 Dec 2004 13:19:26 +0000
changeset 759 6d087784a08a
parent 758 bd9e868b9fae
child 760 f659cca20dac
(svn r1215) Feature: You can now make a custom currency by chosing "Custom..."
gui.h
lang/english.txt
settings.c
settings.h
settings_gui.c
strings.c
table/currency.h
ttd.h
variables.h
--- a/gui.h	Wed Dec 22 01:32:30 2004 +0000
+++ b/gui.h	Wed Dec 22 13:19:26 2004 +0000
@@ -13,6 +13,7 @@
 void ShowGameDifficulty();
 void ShowPatchesSelection();
 void ShowNewgrf();
+void ShowCustCurrency();
 
 /* graph_gui.c */
 void ShowOperatingProfitGraph();
--- a/lang/english.txt	Wed Dec 22 01:32:30 2004 +0000
+++ b/lang/english.txt	Wed Dec 22 13:19:26 2004 +0000
@@ -884,6 +884,7 @@
 STR_CURR_CHF							:Swiss Franc (CHF)
 STR_CURR_NLG							:Dutch Guilder (NLG)
 STR_CURR_ITL							:Italian Lira (ITL)
+STR_CURR_CUSTOM						:Custom...
 STR_CURR_SEK							:Swedish Krona (SEK)
 STR_CURR_RUR							:Russian Rubel (rur)
 STR_CURR_CZK							:Czech Koruna (CZK)
@@ -2728,6 +2729,16 @@
 STR_NEWGRF_FILENAME						:{BLACK}Filename:
 STR_NEWGRF_GRF_ID						:{BLACK}GRF ID:
 
+STR_CURRENCY_WINDOW								:{WHITE}Custom currency
+STR_CURRENCY_EXCHANGE_RATE				:{LTBLUE}Exchange rate: {ORANGE}{CURRENCY} = {COMMA16} {POUNDSIGN}
+STR_CURRENCY_SEPARATOR						:{LTBLUE}Separator:
+STR_CURRENCY_PREFIX								:{LTBLUE}Prefix:
+STR_CURRENCY_POSTFIX							:{LTBLUE}Postfix:
+STR_CURRENCY_SWITCH_TO_EURO				:{LTBLUE}Switch to Euro: {ORANGE}{INT32}
+STR_CURRENCY_SWITCH_TO_EURO_NEVER	:{LTBLUE}Switch to Euro: {ORANGE}never
+STR_CURRENCY_PREVIEW							:{LTBLUE}Preview: {ORANGE}{CURRENCY}
+STR_CURRENCY_CHANGE_PARAMETER			:{BLACK}Change custom currency parameter
+
 STR_TRAIN							:{BLACK}{TRAIN}
 STR_LORRY							:{BLACK}{LORRY}
 STR_PLANE							:{BLACK}{PLANE}
--- a/settings.c	Wed Dec 22 01:32:30 2004 +0000
+++ b/settings.c	Wed Dec 22 13:19:26 2004 +0000
@@ -1,6 +1,7 @@
 #include "stdafx.h"
 #include "ttd.h"
 #include "sound.h"
+#include "table/currency.h"
 #include "network.h"
 #include "settings.h"
 
@@ -169,7 +170,7 @@
 	while (fgets(buffer, sizeof(buffer), in)) {
 
 		// trim whitespace from the left side
-		for(s=buffer; *s == ' ' || *s == '\t'; s++);
+		for(s=buffer; s[0] == ' ' || s[0] == '\t'; s++);
 
 		// trim whitespace from right side.
 		e = s + strlen(s);
@@ -225,6 +226,15 @@
 
 			// find start of parameter
 			while (*t == '=' || *t == ' ' || *t == '\t') t++;
+
+
+			// remove starting quotation marks
+			if(*t=='\"') t++;
+			// remove ending quotation marks
+			e = t + strlen(t);
+			if(e>t && e[-1] =='\"') e--;
+			*e = 0;
+
 			item->value = pool_strdup(&ini->pool, t, e - t);
 		} else {
 			// it's an orphan item
@@ -504,6 +514,7 @@
 
 	case SDT_STRING:
 	case SDT_STRINGBUF:
+	case SDT_STRINGQUOT:
 	case SDT_INTLIST:
 		return (void*)str;
 	}
@@ -567,6 +578,7 @@
 			*(char**)ptr = strdup((char*)p);
 			break;
 		case SDT_STRINGBUF:
+		case SDT_STRINGQUOT:
 			if (p) ttd_strlcpy((char*)ptr, p, desc->flags >> 16);
 			break;
 		case SDT_INTLIST: {
@@ -681,6 +693,9 @@
 				NOT_REACHED();
 			}
 			break;
+		case SDT_STRINGQUOT:
+			sprintf(buf, "\"%s\"", (char*)ptr);
+			break;
 		case SDT_STRINGBUF:
 			strcpy(buf, (char*)ptr);
 			break;
@@ -889,6 +904,15 @@
 	{NULL,									0,					NULL,					NULL,																						NULL}
 };
 
+static const SettingDesc currency_settings[] = {
+	{"rate",			SDT_UINT16,										(void*)1,		&_currency_specs[23].rate,			NULL},
+	{"separator", SDT_STRINGQUOT | (2) << 16,		".", 				&_currency_specs[23].separator,	NULL},
+	{"to_euro",		SDT_UINT16,										(void*)0,		&_currency_specs[23].to_euro,		NULL},
+	{"pre",				SDT_STRINGQUOT | (16) << 16,	NULL,				&_currency_specs[23].pre,				NULL},
+	{"post",			SDT_STRINGQUOT | (16) << 16,	" credits",	&_currency_specs[23].post,			NULL},
+	{NULL,				0,														NULL,				NULL,														NULL}
+};
+
 typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const void *grpname);
 
 static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc)
@@ -902,6 +926,7 @@
 	proc(ini, gameopt_settings, "gameopt");
 	proc(ini, patch_settings,		"patches");
 	proc(ini, patch_player_settings,		"patches");
+	proc(ini, currency_settings,"currency");
 
 	proc(ini, debug_settings,		"debug");
 }
--- a/settings.h	Wed Dec 22 01:32:30 2004 +0000
+++ b/settings.h	Wed Dec 22 13:19:26 2004 +0000
@@ -9,6 +9,7 @@
 	SDT_STRING,
 	SDT_STRINGBUF,
 	SDT_INTLIST,
+	SDT_STRINGQUOT, // string with quotation marks around it
 
 	SDT_INT8 = 0 << 4,
 	SDT_UINT8 = 1 << 4,
--- a/settings_gui.c	Wed Dec 22 01:32:30 2004 +0000
+++ b/settings_gui.c	Wed Dec 22 13:19:26 2004 +0000
@@ -145,6 +145,8 @@
 			}
 			break;
 		case 5:
+			if (e->dropdown.index == 23)
+				ShowCustCurrency();
 			_opt_mod_ptr->currency = _opt.currency = e->dropdown.index;
 			MarkWholeScreenDirty();
 			break;
@@ -184,7 +186,12 @@
 			break;
 		}
 		break;
+
+	case WE_DESTROY:
+		DeleteWindowById(WC_CUSTOM_CURRENCY, 0);
+		break;
 	}
+
 }
 
 int32 CmdSetRoadDriveSide(int x, int y, uint32 flags, uint32 p1, uint32 p2)
@@ -1262,3 +1269,220 @@
 	w->disabled_state = (1 << 5) | (1 << 6) | (1 << 7);
 }
 
+/* state: 0 = none clicked, 0x01 = first clicked, 0x02 = second clicked */
+void DrawArrowButtons(int x, int y, int state)
+{
+	DrawFrameRect(x, y+1, x+9, y+9, 3, (state&0x01) ? 0x20 : 0);
+	DrawFrameRect(x+10, y+1, x+19, y+9, 3, (state&0x02) ? 0x20 : 0);
+	DrawStringCentered(x+5, y+1, STR_6819, 0);
+	DrawStringCentered(x+15, y+1, STR_681A, 0);
+}
+
+char str_separator[2];
+
+static void CustCurrencyWndProc(Window *w, WindowEvent *e)
+{
+	switch (e->event) {
+	case WE_PAINT: {
+		int x=35, y=20, i=0;
+		int clk = WP(w,def_d).data_1;
+		DrawWindowWidgets(w);
+
+		// exchange rate
+		DrawArrowButtons(10, y, (clk >> (i*2)) & 0x03);
+		SetDParam(0, 1);
+		SetDParam(1, 1);
+		DrawString(x, y + 1, STR_CURRENCY_EXCHANGE_RATE, 0);
+		x = 35;
+		y+=12;
+		i++;
+
+		// separator
+		DrawFrameRect(10, y+1, 29, y+9, 0, ((clk >> (i*2)) & 0x03)?0x20:0x00);
+		x = DrawString(x, y + 1, STR_CURRENCY_SEPARATOR, 0);
+		DoDrawString(str_separator, x + 4, y + 1, 6);
+		x = 35;
+		y+=12;
+		i++;
+
+		// prefix
+		DrawFrameRect(10, y+1, 29, y+9, 0, ((clk >> (i*2)) & 0x03)?0x20:0x00);
+		x = DrawString(x, y + 1, STR_CURRENCY_PREFIX, 0);
+		DoDrawString(_currency_specs[23].pre, x + 4, y + 1, 6);
+		x = 35;
+		y+=12;
+		i++;
+
+		// postfix
+		DrawFrameRect(10, y+1, 29, y+9, 0, ((clk >> (i*2)) & 0x03)?0x20:0x00);
+		x = DrawString(x, y + 1, STR_CURRENCY_POSTFIX, 0);
+		DoDrawString(_currency_specs[23].post, x + 4, y + 1, 6);
+		x = 35;
+		y+=12;
+		i++;
+
+		// switch to euro
+		DrawArrowButtons(10, y, (clk >> (i*2)) & 0x03);
+		SetDParam(0, _currency_specs[23].to_euro);
+		DrawString(x, y + 1, (_currency_specs[23].to_euro)?STR_CURRENCY_SWITCH_TO_EURO:STR_CURRENCY_SWITCH_TO_EURO_NEVER, 0);
+		x = 35;
+		y+=12;
+		i++;
+
+		// Preview
+		y+=12;
+		SetDParam(0, 10000);
+		DrawString(x, y + 1, STR_CURRENCY_PREVIEW, 0);
+	} break;
+
+	case WE_CLICK: {
+		bool edittext = false;
+		int line = (e->click.pt.y - 20)/12;
+		int len;
+		int x = e->click.pt.x;
+		StringID str;
+
+		switch ( line ) {
+			case 0: // rate
+				if ( IS_INT_INSIDE(x, 10, 30) ) { // clicked buttons
+					if (x < 20) {
+						_currency_specs[23].rate = max(1, _currency_specs[23].rate-1);
+						WP(w,def_d).data_1 =  (1 << (line * 2 + 0));
+					} else {
+						_currency_specs[23].rate = min(5000, _currency_specs[23].rate+1);
+						WP(w,def_d).data_1 =  (1 << (line * 2 + 1));
+					}
+				} else { // enter text
+					SetDParam(0, _currency_specs[23].rate);
+					str = STR_CONFIG_PATCHES_INT32;
+					len = 4;
+					edittext = true;
+				}
+			break;
+			case 1: // separator
+				if ( IS_INT_INSIDE(x, 10, 30) )  // clicked button
+					WP(w,def_d).data_1 =  (1 << (line * 2 + 1));
+				str = AllocateName(str_separator, 0);
+				len = 1;
+				edittext = true;
+			break;
+			case 2: // prefix
+				if ( IS_INT_INSIDE(x, 10, 30) )  // clicked button
+					WP(w,def_d).data_1 =  (1 << (line * 2 + 1));
+				str = AllocateName(_currency_specs[23].pre, 0);
+				len = 12;
+				edittext = true;
+			break;
+			case 3: // postfix
+				if ( IS_INT_INSIDE(x, 10, 30) )  // clicked button
+					WP(w,def_d).data_1 =  (1 << (line * 2 + 1));
+				str = AllocateName(_currency_specs[23].post, 0);
+				len = 12;
+				edittext = true;
+			break;
+			case 4: // to euro
+				if ( IS_INT_INSIDE(x, 10, 30) ) { // clicked buttons
+					if (x < 20) {
+						if(_currency_specs[23].to_euro <= 2000) _currency_specs[23].to_euro = 0;
+						else _currency_specs[23].to_euro--;
+						WP(w,def_d).data_1 = (1 << (line * 2 + 0));
+					} else {
+						if(_currency_specs[23].to_euro == 0) _currency_specs[23].to_euro = 2000;
+						else _currency_specs[23].to_euro++;
+						_currency_specs[23].to_euro = min(2090, _currency_specs[23].to_euro);
+						WP(w,def_d).data_1 = (1 << (line * 2 + 1));
+					}
+				} else { // enter text
+					SetDParam(0, _currency_specs[23].to_euro);
+					str = STR_CONFIG_PATCHES_INT32;
+					len = 4;
+					edittext = true;
+				}
+			break;
+		}
+		
+		if(edittext) {
+			WP(w,def_d).data_2 = line;
+			ShowQueryString(
+			str,
+			STR_CURRENCY_CHANGE_PARAMETER,
+			len, // maximum number of characters OR
+			250, // characters up to this width pixels, whichever is satisfied first
+			w->window_class,
+			w->window_number);
+			if (str !=  STR_CONFIG_PATCHES_INT32) DeleteName(str);
+		}
+		
+		w->flags4 |= 5 << WF_TIMEOUT_SHL;
+		SetWindowDirty(w);
+	} break;
+
+	case WE_ON_EDIT_TEXT: {
+			int val;
+			byte *b = e->edittext.str;
+			switch (WP(w,def_d).data_2) {
+				case 0:
+					val = atoi(b);
+					val = clamp(val, 1, 5000);
+					_currency_specs[23].rate = val;
+				break;
+				case 1:
+					_currency_specs[23].separator = b[0];
+					ttd_strlcpy(str_separator, b, 16);
+				break;
+				case 2:
+					ttd_strlcpy(_currency_specs[23].pre, b, 16);
+				break;
+				case 3:
+					ttd_strlcpy(_currency_specs[23].post, b, 16);
+				break;
+				case 4:
+					val = atoi(b);
+					val = clamp(val, 1999, 2090);
+					if (val == 1999) val = 0;
+					_currency_specs[23].to_euro = val;
+				break;
+			}
+		MarkWholeScreenDirty();
+			
+		
+	} break;
+
+	case WE_TIMEOUT:
+		WP(w,def_d).data_1 = 0;
+		SetWindowDirty(w);
+		break;
+
+	case WE_DESTROY:
+		DeleteWindowById(WC_QUERY_STRING, 0);
+		MarkWholeScreenDirty();
+		break;
+	}
+}
+
+static const Widget _cust_currency_widgets[] = {
+{   WWT_CLOSEBOX,    14,     0,    10,     0,    13, STR_00C5,						STR_018B_CLOSE_WINDOW},
+{    WWT_CAPTION,    14,    11,   229,     0,    13, STR_CURRENCY_WINDOW,	STR_018C_WINDOW_TITLE_DRAG_THIS},
+{      WWT_PANEL,    14,     0,   229,    14,   119, 0x0,									STR_NULL},
+{   WIDGETS_END},
+};
+
+static const WindowDesc _cust_currency_desc = {
+	WDP_CENTER, WDP_CENTER, 230, 120,
+	WC_CUSTOM_CURRENCY, 0,
+	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
+	_cust_currency_widgets,
+	CustCurrencyWndProc,
+};
+
+void ShowCustCurrency()
+{
+	Window *w;
+
+	str_separator[0] = _currency_specs[23].separator;
+	str_separator[1] = '\0';
+
+	DeleteWindowById(WC_CUSTOM_CURRENCY, 0);
+	w = AllocateWindowDesc(&_cust_currency_desc);
+}
+
--- a/strings.c	Wed Dec 22 01:32:30 2004 +0000
+++ b/strings.c	Wed Dec 22 13:19:26 2004 +0000
@@ -32,45 +32,6 @@
 	uint16 offsets[32];	// the offsets
 } LanguagePackHeader;
 
-typedef struct {
-	uint16 rate;
-	char separator;
-	byte flags;
-	char pre[4];
-	char post[4];
-} CurrencySpec;
-
-enum {
-	CF_TOEURO_2002 = 1,
-	CF_ISEURO = 2,
-};
-
-static const CurrencySpec _currency_specs[] = {
-	{ 1,   ',', 0,              "\xA3", "" },     // british pounds
-	{ 2,   ',', 0,              "$",    "" },     // us dollars
-	{ 10,  '.', CF_TOEURO_2002, "FF ",  "" },     // french francs
-	{ 4,   '.', CF_TOEURO_2002, "DM ",  "" },     // deutsche mark
-	{ 200, ',', 0,              "\xA5", "" },     // yen
-	{ 200, '.', CF_TOEURO_2002, "Pt",   "" },     // spanish pesetas
-	{ 376, ',', CF_TOEURO_2002, "",     " Ft" },
-	{ 6,   ' ', 0,              "",     " zl" },
-	{ 19,  ',', CF_TOEURO_2002, "ATS ", "" },
-	{ 57,  ',', CF_TOEURO_2002, "BEF ", "" },
-	{ 10,  '.', 0,              "",     " kr" },
-	{ 8,   ',', CF_TOEURO_2002, "FIM ", "" },
-	{ 480, ',', CF_TOEURO_2002, "GRD ", "" },
-	{ 2,   ',', 0,              "CHF ", "" },
-	{ 3,   ',', CF_TOEURO_2002, "NLG ", "" },
-	{ 2730,',', CF_TOEURO_2002, "ITL ", "" },
-	{ 13,  '.', 0,              "",     " kr" },
-	{ 5,   ' ', 0,              "",     " rur" },
-	{ 50,  ',', 0,              "",     " Kc" },
-	{ 130, '.', 0,              "",     " kr" },
-	{ 11,  '.', 0,              "",     " kr" },
-	{ 2,   ',', CF_ISEURO,      "¤",    "" },
-	{ 6,   '.', 0,              "",     " Lei" },
-};
-
 const uint16 _currency_string_list[] = {
 	STR_CURR_POUNDS,
 	STR_CURR_DOLLARS,
@@ -95,6 +56,7 @@
 	STR_CURR_NOK,
 	STR_CURR_EUR,
 	STR_CURR_ROL,
+	STR_CURR_CUSTOM,
 	INVALID_STRING_ID
 };
 
@@ -111,9 +73,10 @@
 	int i;
 	uint mask = 0;
 	for(i=0; i!=lengthof(_currency_specs); i++) {
-		byte flags = _currency_specs[i].flags;
-		if (_cur_year >= (2002-1920) && (flags & CF_TOEURO_2002)) continue;
-		if (_cur_year < (2000-1920) && (flags & CF_ISEURO)) continue;
+		uint16 to_euro = _currency_specs[i].to_euro;
+		if (i == 23) mask |= (1 << 23); // always allow custom currency
+		if (to_euro != CF_NOEURO && to_euro != CF_ISEURO && _cur_year >= (to_euro-1920)) continue;
+		if (_cur_year < (2000-1920) && (to_euro == CF_ISEURO)) continue;
 		mask |= (1 << i);
 	}
 	return mask;
@@ -121,7 +84,9 @@
 
 void CheckSwitchToEuro()
 {
-	if (_cur_year >= (2002-1920) && _currency_specs[_opt.currency].flags & CF_TOEURO_2002) {
+	if (_currency_specs[_opt.currency].to_euro != CF_NOEURO &&
+			_currency_specs[_opt.currency].to_euro != CF_ISEURO &&
+			_cur_year >= (_currency_specs[_opt.currency].to_euro-1920)) {
 		_opt.currency = 21; // this is the index of euro above.
 		AddNewsItem(STR_EURO_INTRODUCE, NEWS_FLAGS(NM_NORMAL,0,NT_ECONOMY,0), 0, 0);
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/table/currency.h	Wed Dec 22 13:19:26 2004 +0000
@@ -0,0 +1,26 @@
+
+CurrencySpec _currency_specs[] = {
+{ 1,   ',', CF_NOEURO,              "\xA3", "" },     // british pounds
+{ 2,   ',', CF_NOEURO,              "$",    "" },     // us dollars
+{ 10,  '.', 2002, "FF ",  "" },     // french francs
+{ 4,   '.', 2002, "DM ",  "" },     // deutsche mark
+{ 200, ',', CF_NOEURO,              "\xA5", "" },     // yen
+{ 200, '.', 2002, "Pt",   "" },     // spanish pesetas
+{ 376, ',', 2002, "",     " Ft" },
+{ 6,   ' ', CF_NOEURO,              "",     " zl" },
+{ 19,  ',', 2002, "ATS ", "" },
+{ 57,  ',', 2002, "BEF ", "" },
+{ 10,  '.', CF_NOEURO,              "",     " kr" },
+{ 8,   ',', 2002, "FIM ", "" },
+{ 480, ',', 2002, "GRD ", "" },
+{ 2,   ',', CF_NOEURO,              "CHF ", "" },
+{ 3,   ',', 2002, "NLG ", "" },
+{ 2730,',', 2002, "ITL ", "" },
+{ 13,  '.', CF_NOEURO,              "",     " kr" },
+{ 5,   ' ', CF_NOEURO,              "",     " rur" },
+{ 50,  ',', CF_NOEURO,              "",     " Kc" },
+{ 130, '.', CF_NOEURO,              "",     " kr" },
+{ 11,  '.', CF_NOEURO,              "",     " kr" },
+{ 2,   ',', CF_ISEURO,      "¤",    "" },
+{ 6,   '.', CF_NOEURO,              "",     " Lei" },
+};
--- a/ttd.h	Wed Dec 22 01:32:30 2004 +0000
+++ b/ttd.h	Wed Dec 22 13:19:26 2004 +0000
@@ -438,6 +438,7 @@
 	WC_EXTRA_VIEW_PORT = 0x48,
 	WC_CLIENT_LIST = 0x49,
 	WC_NETWORK_STATUS_WINDOW = 0x4A,
+	WC_CUSTOM_CURRENCY = 0x4B,
 };
 
 
--- a/variables.h	Wed Dec 22 01:32:30 2004 +0000
+++ b/variables.h	Wed Dec 22 13:19:26 2004 +0000
@@ -36,6 +36,21 @@
 // These are the options for the new game
 VARDEF GameOptions _new_opt;
 
+enum {
+	CF_NOEURO = 0,
+	CF_ISEURO = 1,
+};
+
+typedef struct {
+	uint16 rate;
+	char separator;
+	uint16 to_euro;
+	char pre[16];
+	char post[16];
+} CurrencySpec;
+
+CurrencySpec _currency_specs[24];
+
 // Current date
 VARDEF uint16 _date;
 VARDEF uint16 _date_fract;