1
0
Fork 0

(svn r17987) [0.7] -Backport from trunk:

- Fix: [NewGRF] 'subtract-in' is also signed for production callback version 0 (r17857)
- Fix: [NewGRF] _date_fract runs from 0 to 73 since r2041. Variable 0x09 should not (r17824)
- Fix: Do not fail hard when no soundcard could be detected; just fall back on the null-driver [FS#3268] (r17788)
- Fix: CJK languages do not have spaces, so for adding newlines (multi line strings) we need to (properly) handle the case when there are no spaces instead of truncating the string [FS#3264] (r17772)
- Fix: Powernaut Helicopter got wrong 'load amount' (r17758)
- Change: Prefer extmidi over allegro midi and allegro over null driver [FS#3272] (r17875)
release/0.7
rubidium 2009-11-06 22:53:21 +00:00
parent 9360409b4e
commit 072270f9b9
13 changed files with 64 additions and 31 deletions

View File

@ -50,6 +50,8 @@ const uint8 _engine_offsets[4] = {
lengthof(_orig_rail_vehicle_info) + lengthof(_orig_road_vehicle_info) + lengthof(_orig_ship_vehicle_info), 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]; const uint EngineOverrideManager::NUM_DEFAULT_ENGINES = _engine_counts[VEH_TRAIN] + _engine_counts[VEH_ROAD] + _engine_counts[VEH_SHIP] + _engine_counts[VEH_AIRCRAFT];
Engine::Engine() : Engine::Engine() :

View File

@ -593,12 +593,13 @@ void DrawStringCenterUnderlineTruncated(int xl, int xr, int y, StringID str, Tex
* starting with index 0 is the real string end. * starting with index 0 is the real string end.
* *
* @param str string to check and correct for length restrictions * @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 * @param maxw the maximum width the string can have on one line
* @return return a 32bit wide number consisting of 2 packed values: * @return return a 32bit wide number consisting of 2 packed values:
* 0 - 15 the number of lines ADDED to the string * 0 - 15 the number of lines ADDED to the string
* 16 - 31 the fontsize in which the length calculation was done at * 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; FontSize size = _cur_fontsize;
int num = 0; int num = 0;
@ -606,6 +607,7 @@ uint32 FormatStringLinebreaks(char *str, int maxw)
assert(maxw > 0); assert(maxw > 0);
for (;;) { for (;;) {
/* The character *after* the last space. */
char *last_space = NULL; char *last_space = NULL;
int w = 0; int w = 0;
@ -615,18 +617,49 @@ uint32 FormatStringLinebreaks(char *str, int maxw)
if (IsWhitespace(c)) last_space = str; if (IsWhitespace(c)) last_space = str;
if (IsPrintable(c)) { if (IsPrintable(c)) {
w += GetCharacterWidth(size, c); int char_w = GetCharacterWidth(size, c);
/* string is longer than maximum width so we need to decide what to w += char_w;
* 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 */
if (w > maxw) { if (w > maxw) {
if (last_space == NULL) { /* The string is longer than maximum width so we need to decide
*Utf8PrevChar(str) = '\0'; * 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); 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; break;
} }
} else { } else {
@ -695,7 +728,7 @@ int GetStringHeight(StringID str, int maxw)
GetString(buffer, str, lastof(buffer)); GetString(buffer, str, lastof(buffer));
uint32 tmp = FormatStringLinebreaks(buffer, maxw); uint32 tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw);
return GetMultilineStringHeight(buffer, GB(tmp, 0, 16)); 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)); GetString(buffer, str, lastof(buffer));
tmp = FormatStringLinebreaks(buffer, maxw); tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw);
num = GB(tmp, 0, 16); num = GB(tmp, 0, 16);
mt = GetCharacterHeight((FontSize)GB(tmp, 16, 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) uint DrawStringMultiLine(int x, int y, StringID str, int maxw, int maxh)
{ {
char buffer[DRAW_STRING_BUFFER]; char buffer[DRAW_STRING_BUFFER];
uint32 tmp;
int num, mt;
uint total_height; uint total_height;
const char *src; const char *src;
WChar c; WChar c;
GetString(buffer, str, lastof(buffer)); GetString(buffer, str, lastof(buffer));
tmp = FormatStringLinebreaks(buffer, maxw); uint32 tmp = FormatStringLinebreaks(buffer, lastof(buffer), maxw);
num = GB(tmp, 0, 16); 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; total_height = (num + 1) * mt;
if (maxh != -1 && (int)total_height > maxh) { if (maxh != -1 && (int)total_height > maxh) {

View File

@ -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); void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
Dimension GetStringBoundingBox(const char *str); 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); int GetStringHeight(StringID str, int maxw);
void LoadStringWidthTable(); void LoadStringWidthTable();
void DrawStringMultiCenter(int x, int y, StringID str, int maxw); void DrawStringMultiCenter(int x, int y, StringID str, int maxw);

View File

@ -24,7 +24,7 @@ public:
class FMusicDriver_Allegro: public MusicDriverFactory<FMusicDriver_Allegro> { class FMusicDriver_Allegro: public MusicDriverFactory<FMusicDriver_Allegro> {
public: public:
static const int priority = 1; static const int priority = 2;
/* virtual */ const char *GetName() { return "allegro"; } /* virtual */ const char *GetName() { return "allegro"; }
/* virtual */ const char *GetDescription() { return "Allegro MIDI Driver"; } /* virtual */ const char *GetDescription() { return "Allegro MIDI Driver"; }
/* virtual */ Driver *CreateInstance() { return new MusicDriver_Allegro(); } /* virtual */ Driver *CreateInstance() { return new MusicDriver_Allegro(); }

View File

@ -32,7 +32,7 @@ public:
class FMusicDriver_ExtMidi: public MusicDriverFactory<FMusicDriver_ExtMidi> { class FMusicDriver_ExtMidi: public MusicDriverFactory<FMusicDriver_ExtMidi> {
public: public:
static const int priority = 1; static const int priority = 3;
/* virtual */ const char *GetName() { return "extmidi"; } /* virtual */ const char *GetName() { return "extmidi"; }
/* virtual */ const char *GetDescription() { return "External MIDI Driver"; } /* virtual */ const char *GetDescription() { return "External MIDI Driver"; }
/* virtual */ Driver *CreateInstance() { return new MusicDriver_ExtMidi(); } /* virtual */ Driver *CreateInstance() { return new MusicDriver_ExtMidi(); }

View File

@ -24,7 +24,7 @@ public:
class FMusicDriver_Null: public MusicDriverFactory<FMusicDriver_Null> { class FMusicDriver_Null: public MusicDriverFactory<FMusicDriver_Null> {
public: public:
static const int priority = 0; static const int priority = 1;
/* virtual */ const char *GetName() { return "null"; } /* virtual */ const char *GetName() { return "null"; }
/* virtual */ const char *GetDescription() { return "Null Music Driver"; } /* virtual */ const char *GetDescription() { return "Null Music Driver"; }
/* virtual */ Driver *CreateInstance() { return new MusicDriver_Null(); } /* virtual */ Driver *CreateInstance() { return new MusicDriver_Null(); }

View File

@ -79,7 +79,7 @@ void CDECL NetworkAddChatMessage(TextColour colour, uint8 duration, const char *
Utf8TrimString(buf, DRAW_STRING_BUFFER); Utf8TrimString(buf, DRAW_STRING_BUFFER);
/* Force linebreaks for strings that are too long */ /* 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; if (lines >= MAX_CHAT_MESSAGES) return;
msg_count = GetChatMessageCount(); msg_count = GetChatMessageCount();

View File

@ -3022,10 +3022,10 @@ static void NewSpriteGroup(byte *buf, size_t len)
group->g.indprod.version = type; group->g.indprod.version = type;
if (type == 0) { if (type == 0) {
for (uint i = 0; i < 3; i++) { 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++) { 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); group->g.indprod.again = grf_load_byte(&buf);
} else { } else {
@ -3774,7 +3774,7 @@ bool GetGlobalVariable(byte param, uint32 *value)
return true; return true;
case 0x09: // date fraction case 0x09: // date fraction
*value = _date_fract; *value = _date_fract * 885;
return true; return true;
case 0x0A: // animation counter case 0x0A: // animation counter

View File

@ -551,7 +551,7 @@ bool CheckIfCallBackAllowsAvailability(IndustryType type, IndustryAvailabilityCa
return true; 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; return use_register ? (int32)GetRegister(field) : field;
} }

View File

@ -165,8 +165,8 @@ struct TileLayoutSpriteGroup {
struct IndustryProductionSpriteGroup { struct IndustryProductionSpriteGroup {
uint8 version; uint8 version;
uint16 substract_input[3]; int16 substract_input[3]; // signed
uint16 add_output[2]; uint16 add_output[2]; // unsigned
uint8 again; uint8 again;
}; };

View File

@ -18,7 +18,7 @@ public:
class FSoundDriver_Allegro: public SoundDriverFactory<FSoundDriver_Allegro> { class FSoundDriver_Allegro: public SoundDriverFactory<FSoundDriver_Allegro> {
public: public:
static const int priority = 5; static const int priority = 4;
/* virtual */ const char *GetName() { return "allegro"; } /* virtual */ const char *GetName() { return "allegro"; }
/* virtual */ const char *GetDescription() { return "Allegro Sound Driver"; } /* virtual */ const char *GetDescription() { return "Allegro Sound Driver"; }
/* virtual */ Driver *CreateInstance() { return new SoundDriver_Allegro(); } /* virtual */ Driver *CreateInstance() { return new SoundDriver_Allegro(); }

View File

@ -16,7 +16,7 @@ public:
class FSoundDriver_Null: public SoundDriverFactory<FSoundDriver_Null> { class FSoundDriver_Null: public SoundDriverFactory<FSoundDriver_Null> {
public: public:
static const int priority = 0; static const int priority = 1;
/* virtual */ const char *GetName() { return "null"; } /* virtual */ const char *GetName() { return "null"; }
/* virtual */ const char *GetDescription() { return "Null Sound Driver"; } /* virtual */ const char *GetDescription() { return "Null Sound Driver"; }
/* virtual */ Driver *CreateInstance() { return new SoundDriver_Null(); } /* virtual */ Driver *CreateInstance() { return new SoundDriver_Null(); }

View File

@ -325,7 +325,7 @@ static const EngineInfo _orig_engine_info[] = {
MA( 23832, 20, 20, 99, Y), // 252 Flashbang Wizzer MA( 23832, 20, 20, 99, Y), // 252 Flashbang Wizzer
MA( 13575, 20, 20, 40, T|A|S ), // 253 Tricario Helicopter MA( 13575, 20, 20, 40, T|A|S ), // 253 Tricario Helicopter
MA( 28215, 20, 20, 30, T|A|S ), // 254 Guru X2 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 Y
#undef S #undef S