summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gui.h1
-rw-r--r--lang/english.txt11
-rw-r--r--settings.c27
-rw-r--r--settings.h1
-rw-r--r--settings_gui.c224
-rw-r--r--strings.c51
-rw-r--r--table/currency.h26
-rw-r--r--ttd.h1
-rw-r--r--variables.h15
9 files changed, 313 insertions, 44 deletions
diff --git a/gui.h b/gui.h
index 0da9e557c..0786c8c53 100644
--- a/gui.h
+++ b/gui.h
@@ -13,6 +13,7 @@ void ShowGameOptions();
void ShowGameDifficulty();
void ShowPatchesSelection();
void ShowNewgrf();
+void ShowCustCurrency();
/* graph_gui.c */
void ShowOperatingProfitGraph();
diff --git a/lang/english.txt b/lang/english.txt
index 6d4b3b316..0f4ed9cf8 100644
--- a/lang/english.txt
+++ b/lang/english.txt
@@ -884,6 +884,7 @@ STR_CURR_GRD :Greek Drachma (GRD)
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_NO_FILES_INSTALLED :{BLACK}There are currently no newgrf files in
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}
diff --git a/settings.c b/settings.c
index da980d49f..e6351e509 100644
--- a/settings.c
+++ b/settings.c
@@ -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 @@ static IniFile *ini_load(const char *filename)
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 @@ static IniFile *ini_load(const char *filename)
// 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 @@ static const void *string_to_val(const SettingDesc *desc, const char *str)
case SDT_STRING:
case SDT_STRINGBUF:
+ case SDT_STRINGQUOT:
case SDT_INTLIST:
return (void*)str;
}
@@ -567,6 +578,7 @@ static void load_setting_desc(IniFile *ini, const SettingDesc *desc, const void
*(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 @@ static void save_setting_desc(IniFile *ini, const SettingDesc *desc, const void
NOT_REACHED();
}
break;
+ case SDT_STRINGQUOT:
+ sprintf(buf, "\"%s\"", (char*)ptr);
+ break;
case SDT_STRINGBUF:
strcpy(buf, (char*)ptr);
break;
@@ -889,6 +904,15 @@ const SettingDesc patch_settings[] = {
{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 @@ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc)
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");
}
diff --git a/settings.h b/settings.h
index ed6545924..e4bf27601 100644
--- a/settings.h
+++ b/settings.h
@@ -9,6 +9,7 @@ enum SettingDescType {
SDT_STRING,
SDT_STRINGBUF,
SDT_INTLIST,
+ SDT_STRINGQUOT, // string with quotation marks around it
SDT_INT8 = 0 << 4,
SDT_UINT8 = 1 << 4,
diff --git a/settings_gui.c b/settings_gui.c
index 734532ff9..1f2c8c164 100644
--- a/settings_gui.c
+++ b/settings_gui.c
@@ -145,6 +145,8 @@ static void GameOptionsWndProc(Window *w, WindowEvent *e)
}
break;
case 5:
+ if (e->dropdown.index == 23)
+ ShowCustCurrency();
_opt_mod_ptr->currency = _opt.currency = e->dropdown.index;
MarkWholeScreenDirty();
break;
@@ -184,7 +186,12 @@ static void GameOptionsWndProc(Window *w, WindowEvent *e)
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 @@ void ShowNewgrf()
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);
+}
+
diff --git a/strings.c b/strings.c
index 5a738aac3..a6c2d5ee0 100644
--- a/strings.c
+++ b/strings.c
@@ -32,45 +32,6 @@ typedef struct {
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 @@ const uint16 _currency_string_list[] = {
STR_CURR_NOK,
STR_CURR_EUR,
STR_CURR_ROL,
+ STR_CURR_CUSTOM,
INVALID_STRING_ID
};
@@ -111,9 +73,10 @@ uint GetMaskOfAllowedCurrencies()
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 @@ uint GetMaskOfAllowedCurrencies()
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);
}
diff --git a/table/currency.h b/table/currency.h
new file mode 100644
index 000000000..7e99e8f26
--- /dev/null
+++ b/table/currency.h
@@ -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" },
+};
diff --git a/ttd.h b/ttd.h
index 0265d21f1..35bcc6354 100644
--- a/ttd.h
+++ b/ttd.h
@@ -438,6 +438,7 @@ enum {
WC_EXTRA_VIEW_PORT = 0x48,
WC_CLIENT_LIST = 0x49,
WC_NETWORK_STATUS_WINDOW = 0x4A,
+ WC_CUSTOM_CURRENCY = 0x4B,
};
diff --git a/variables.h b/variables.h
index afaa72905..2d9c2ff2c 100644
--- a/variables.h
+++ b/variables.h
@@ -36,6 +36,21 @@ VARDEF GameOptions _opt;
// 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;