diff --git a/src/engine.cpp b/src/engine.cpp index cf2a77cba1..7a9136423a 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -50,6 +50,8 @@ const uint8 _engine_offsets[4] = { lengthof(_orig_rail_vehicle_info) + lengthof(_orig_road_vehicle_info) + lengthof(_orig_ship_vehicle_info), }; +assert_compile(lengthof(_orig_rail_vehicle_info) + lengthof(_orig_road_vehicle_info) + lengthof(_orig_ship_vehicle_info) + lengthof(_orig_aircraft_vehicle_info) == lengthof(_orig_engine_info)); + const uint EngineOverrideManager::NUM_DEFAULT_ENGINES = _engine_counts[VEH_TRAIN] + _engine_counts[VEH_ROAD] + _engine_counts[VEH_SHIP] + _engine_counts[VEH_AIRCRAFT]; Engine::Engine() : diff --git a/src/gfx.cpp b/src/gfx.cpp index 700c64d618..a56c9f20c4 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -593,12 +593,13 @@ void DrawStringCenterUnderlineTruncated(int xl, int xr, int y, StringID str, Tex * starting with index 0 is the real string end. * * @param str string to check and correct for length restrictions + * @param last the last valid location (for '\0') in the buffer of str * @param maxw the maximum width the string can have on one line * @return return a 32bit wide number consisting of 2 packed values: * 0 - 15 the number of lines ADDED to the string * 16 - 31 the fontsize in which the length calculation was done at */ -uint32 FormatStringLinebreaks(char *str, int maxw) +uint32 FormatStringLinebreaks(char *str, const char *last, int maxw) { FontSize size = _cur_fontsize; int num = 0; @@ -606,6 +607,7 @@ uint32 FormatStringLinebreaks(char *str, int maxw) assert(maxw > 0); for (;;) { + /* The character *after* the last space. */ char *last_space = NULL; int w = 0; @@ -615,18 +617,49 @@ uint32 FormatStringLinebreaks(char *str, int maxw) if (IsWhitespace(c)) last_space = str; if (IsPrintable(c)) { - w += GetCharacterWidth(size, c); - /* string is longer than maximum width so we need to decide what to - * do. We can do two things: - * 1. If no whitespace was found at all up until now (on this line) then - * we will truncate the string and bail out. - * 2. In all other cases force a linebreak at the last seen whitespace */ + int char_w = GetCharacterWidth(size, c); + w += char_w; if (w > maxw) { - if (last_space == NULL) { - *Utf8PrevChar(str) = '\0'; + /* The string is longer than maximum width so we need to decide + * what to do with it. */ + if (w == char_w) { + /* The character is wider than allowed width; don't know + * what to do with this case... bail out! */ return num + (size << 16); } - str = last_space; + if (last_space == NULL) { + /* No space has been found. Just terminate at our current + * location. This usually happens for languages that do not + * require spaces in strings, like Chinese, Japanese and + * Korean. For other languages terminating mid-word might + * not be the best, but terminating the whole string instead + * of continuing the word at the next line is worse. */ + str = Utf8PrevChar(str); + size_t len = strlen(str); + char *terminator = str + len; + + /* The string location + length of the string + 1 for '\0' + * always fits; otherwise there's no trailing '\0' and it + * it not a valid string. */ + assert(terminator <= last); + assert(*terminator == '\0'); + + /* If the string is too long we have to terminate it earlier. */ + if (terminator == last) { + /* Get the 'begin' of the previous character and make that + * the terminator of the string; we truncate it 'early'. */ + *Utf8PrevChar(terminator) = '\0'; + len = strlen(str); + } + /* Also move the terminator! */ + memmove(str + 1, str, len + 1); + *str = '\0'; + /* str needs to point to the character *after* the last space */ + str++; + } else { + /* A space is found; perfect place to terminate */ + str = last_space; + } break; } } else { @@ -695,7 +728,7 @@ int GetStringHeight(StringID str, int maxw) GetString(buffer, str, lastof(buffer)); - uint32 tmp = FormatStringLinebreaks(buffer, maxw); + uint32 tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw); return GetMultilineStringHeight(buffer, GB(tmp, 0, 16)); } @@ -716,7 +749,7 @@ void DrawStringMultiCenter(int x, int y, StringID str, int maxw) GetString(buffer, str, lastof(buffer)); - tmp = FormatStringLinebreaks(buffer, maxw); + tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw); num = GB(tmp, 0, 16); mt = GetCharacterHeight((FontSize)GB(tmp, 16, 16)); @@ -755,18 +788,16 @@ void DrawStringMultiCenter(int x, int y, StringID str, int maxw) uint DrawStringMultiLine(int x, int y, StringID str, int maxw, int maxh) { char buffer[DRAW_STRING_BUFFER]; - uint32 tmp; - int num, mt; uint total_height; const char *src; WChar c; GetString(buffer, str, lastof(buffer)); - tmp = FormatStringLinebreaks(buffer, maxw); - num = GB(tmp, 0, 16); + uint32 tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw); + int num = GB(tmp, 0, 16); - mt = GetCharacterHeight((FontSize)GB(tmp, 16, 16)); + int mt = GetCharacterHeight((FontSize)GB(tmp, 16, 16)); total_height = (num + 1) * mt; if (maxh != -1 && (int)total_height > maxh) { diff --git a/src/gfx_func.h b/src/gfx_func.h index eedf346043..ccc57c0ca8 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -109,7 +109,7 @@ void GfxDrawLine(int left, int top, int right, int bottom, int colour); void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3); Dimension GetStringBoundingBox(const char *str); -uint32 FormatStringLinebreaks(char *str, int maxw); +uint32 FormatStringLinebreaks(char *str, const char *last, int maxw); int GetStringHeight(StringID str, int maxw); void LoadStringWidthTable(); void DrawStringMultiCenter(int x, int y, StringID str, int maxw); diff --git a/src/music/allegro_m.h b/src/music/allegro_m.h index 1bc62d65c3..b37103bc33 100644 --- a/src/music/allegro_m.h +++ b/src/music/allegro_m.h @@ -24,7 +24,7 @@ public: class FMusicDriver_Allegro: public MusicDriverFactory { public: - static const int priority = 1; + static const int priority = 2; /* virtual */ const char *GetName() { return "allegro"; } /* virtual */ const char *GetDescription() { return "Allegro MIDI Driver"; } /* virtual */ Driver *CreateInstance() { return new MusicDriver_Allegro(); } diff --git a/src/music/extmidi.h b/src/music/extmidi.h index bae1e1b4ff..dfd64290a7 100644 --- a/src/music/extmidi.h +++ b/src/music/extmidi.h @@ -32,7 +32,7 @@ public: class FMusicDriver_ExtMidi: public MusicDriverFactory { public: - static const int priority = 1; + static const int priority = 3; /* virtual */ const char *GetName() { return "extmidi"; } /* virtual */ const char *GetDescription() { return "External MIDI Driver"; } /* virtual */ Driver *CreateInstance() { return new MusicDriver_ExtMidi(); } diff --git a/src/music/null_m.h b/src/music/null_m.h index bced36cf3f..aa96c300b9 100644 --- a/src/music/null_m.h +++ b/src/music/null_m.h @@ -24,7 +24,7 @@ public: class FMusicDriver_Null: public MusicDriverFactory { public: - static const int priority = 0; + static const int priority = 1; /* virtual */ const char *GetName() { return "null"; } /* virtual */ const char *GetDescription() { return "Null Music Driver"; } /* virtual */ Driver *CreateInstance() { return new MusicDriver_Null(); } diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index 5796c53443..d54b9f1af6 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.cpp @@ -79,7 +79,7 @@ void CDECL NetworkAddChatMessage(TextColour colour, uint8 duration, const char * Utf8TrimString(buf, DRAW_STRING_BUFFER); /* Force linebreaks for strings that are too long */ - lines = GB(FormatStringLinebreaks(buf, _chatmsg_box.width - 8), 0, 16) + 1; + lines = GB(FormatStringLinebreaks(buf, lastof(buf), _chatmsg_box.width - 8), 0, 16) + 1; if (lines >= MAX_CHAT_MESSAGES) return; msg_count = GetChatMessageCount(); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index e0f4a4c9b3..9bf1b30d58 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -3022,10 +3022,10 @@ static void NewSpriteGroup(byte *buf, size_t len) group->g.indprod.version = type; if (type == 0) { for (uint i = 0; i < 3; i++) { - group->g.indprod.substract_input[i] = grf_load_word(&buf); + group->g.indprod.substract_input[i] = (int16)grf_load_word(&buf); // signed } for (uint i = 0; i < 2; i++) { - group->g.indprod.add_output[i] = grf_load_word(&buf); + group->g.indprod.add_output[i] = grf_load_word(&buf); // unsigned } group->g.indprod.again = grf_load_byte(&buf); } else { @@ -3774,7 +3774,7 @@ bool GetGlobalVariable(byte param, uint32 *value) return true; case 0x09: // date fraction - *value = _date_fract; + *value = _date_fract * 885; return true; case 0x0A: // animation counter diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 73397eb7c5..373e74f3e1 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -551,7 +551,7 @@ bool CheckIfCallBackAllowsAvailability(IndustryType type, IndustryAvailabilityCa return true; } -static int32 DerefIndProd(uint field, bool use_register) +static int32 DerefIndProd(int field, bool use_register) { return use_register ? (int32)GetRegister(field) : field; } diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 0b83934d90..bc078808f2 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -165,8 +165,8 @@ struct TileLayoutSpriteGroup { struct IndustryProductionSpriteGroup { uint8 version; - uint16 substract_input[3]; - uint16 add_output[2]; + int16 substract_input[3]; // signed + uint16 add_output[2]; // unsigned uint8 again; }; diff --git a/src/sound/allegro_s.h b/src/sound/allegro_s.h index 181f45059f..08268806a2 100644 --- a/src/sound/allegro_s.h +++ b/src/sound/allegro_s.h @@ -18,7 +18,7 @@ public: class FSoundDriver_Allegro: public SoundDriverFactory { public: - static const int priority = 5; + static const int priority = 4; /* virtual */ const char *GetName() { return "allegro"; } /* virtual */ const char *GetDescription() { return "Allegro Sound Driver"; } /* virtual */ Driver *CreateInstance() { return new SoundDriver_Allegro(); } diff --git a/src/sound/null_s.h b/src/sound/null_s.h index 49581fc187..bc459097c9 100644 --- a/src/sound/null_s.h +++ b/src/sound/null_s.h @@ -16,7 +16,7 @@ public: class FSoundDriver_Null: public SoundDriverFactory { public: - static const int priority = 0; + static const int priority = 1; /* virtual */ const char *GetName() { return "null"; } /* virtual */ const char *GetDescription() { return "Null Sound Driver"; } /* virtual */ Driver *CreateInstance() { return new SoundDriver_Null(); } diff --git a/src/table/engines.h b/src/table/engines.h index c014a7e0ce..b59f2a245c 100644 --- a/src/table/engines.h +++ b/src/table/engines.h @@ -325,7 +325,7 @@ static const EngineInfo _orig_engine_info[] = { MA( 23832, 20, 20, 99, Y), // 252 Flashbang Wizzer MA( 13575, 20, 20, 40, T|A|S ), // 253 Tricario Helicopter MA( 28215, 20, 20, 30, T|A|S ), // 254 Guru X2 Helicopter - MK( 13575, 20, 20, 99, Y), // 255 + MA( 13575, 20, 20, 99, Y), // 255 Powernaut Helicopter }; #undef Y #undef S