From 4f4fa940d816af32ca9fb34458b3359e53d74f4b Mon Sep 17 00:00:00 2001 From: dominik Date: Wed, 22 Dec 2004 13:19:26 +0000 Subject: (svn r1215) Feature: You can now make a custom currency by chosing "Custom..." --- gui.h | 1 + lang/english.txt | 11 +++ settings.c | 27 ++++++- settings.h | 1 + settings_gui.c | 224 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ strings.c | 51 ++----------- table/currency.h | 26 +++++++ ttd.h | 1 + variables.h | 15 ++++ 9 files changed, 313 insertions(+), 44 deletions(-) create mode 100644 table/currency.h 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; -- cgit v1.2.3-70-g09d2