Various NML related questions

Discussions about the technical aspects of graphics development, including NewGRF tools and utilities.

Moderator: Graphics Moderators

Alberth
OpenTTD Developer
OpenTTD Developer
Posts: 4766
Joined: 09 Sep 2007 05:03
Location: home

Re: Various NML related questions

Post by Alberth »

x / (1 << 21) looks like discarding a fraction of 21 bits, to me.

NewGRF only has integer numbers, so there is nothing between 0 and 1 (or 1 and 2, etc).
Suppose you want some numbers between them anyway, what to do?

The trick is (in the decimal system), multiply by 10. Thus 0 -> 0, and 1 -> 10, and 2 -> 20, etc.
'Suddenly', I have 1, 2, 3, .. 9 between 0 and 10 (corresponding with 0.1, 0.2, .. 0.9), yet I still use integer numbers only. You can add, subtract, and even multiply (with a bit of care) in this integer world, and it all works as expected. Eg 2 + 18 (0.2 + 1.8) -> 20 (2.0).

So how to get back to the original 0, 1, 2 values (which have become 0, 10, 20, etc)? That's also easy, just / 10 (the reverse operation of multiply by 10). Obviously, there are some rounding problems that need to be taken care of here, you may want to add 5 (0.5) before dividing.

In NewGRF you can do the same trick, except multiplying and dividing by 10 is much slower than using a power of 2. There is nothing against using 1 << 21 as multiplication factor, which gives you more than 6 digits precision, namely the lowest 21 bits become the fraction (much like the last decimal was the fraction in my decimal example). / (1 << 21) then means drop the lowest 21 bits, or go back to the value without the fraction.

Edit: Why 21 bits? no idea, but given that an integer is 32 bit (31 if you don't want sign trouble), so maybe the author of the code had 10 bits in the original integer world, and decided he wanted as much fraction as possible?
Being a retired OpenTTD developer does not mean I know what I am doing.
User avatar
3iff
Tycoon
Tycoon
Posts: 1105
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

I bow to your superior knowledge. I'm ok with decimals but binary leaves me in bits.
User avatar
Sylf
President
President
Posts: 957
Joined: 23 Nov 2010 21:25
Location: ::1

Re: Various NML related questions

Post by Sylf »

3iff wrote:I'm ok with decimals but binary leaves me in bits.
:lol:
Eddi
Tycoon
Tycoon
Posts: 8289
Joined: 17 Jan 2007 00:14

Re: Various NML related questions

Post by Eddi »

Alberth wrote:x / (1 << 21)
am i the only one here thinking that "x >> 21" should do the same thing? (save for some signed/unsigned troubles)
Alberth
OpenTTD Developer
OpenTTD Developer
Posts: 4766
Joined: 09 Sep 2007 05:03
Location: home

Re: Various NML related questions

Post by Alberth »

Eddi wrote:
Alberth wrote:x / (1 << 21)
am i the only one here thinking that "x >> 21" should do the same thing? (save for some signed/unsigned troubles)
No you are not, but I didn't want to drag sign bit considerations into the explanation.
Being a retired OpenTTD developer does not mean I know what I am doing.
User avatar
3iff
Tycoon
Tycoon
Posts: 1105
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

I want an industry to generate a news message triggered by a custom event. I've had a look through the NML wiki (as always) but I can't see a way to do it. I'd basically be checking a perm register or two (which I now mostly understand) but I don't know how to make it issue a news report - or how I might customise what it might say.

If it is possible, could someone point me in the right direction?
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: Various NML related questions

Post by planetmaker »

3iff wrote:I want an industry to generate a news message triggered by a custom event. I've had a look through the NML wiki (as always) but I can't see a way to do it. I'd basically be checking a perm register or two (which I now mostly understand) but I don't know how to make it issue a news report - or how I might customise what it might say.

If it is possible, could someone point me in the right direction?
Not sure what you mean with 'custom events' - probably the answer is 'no, you cannot do that'.
You have, of course, the production callback(s) which can return a custom string instead of the defaults. See http://newgrf-specs.tt-wiki.net/wiki/NML:Industries
User avatar
3iff
Tycoon
Tycoon
Posts: 1105
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

That's me explaining things badly...

Basically, an industry might have a reserve of raw materials. When it reaches a trigger point, I'd like to pop up a news report saying "reserves are running low" or something similar just to warn the player. I'd do a check every so often (somehow).

Is it this...?
Setting bit 8 replaces the news message with a custom message, read from register 0x100 bits 0 .. 15.

Setting bit 8 of what? and how do I set the register 0x100 bits 0 .. 15 ?

Sorry if these are basic things, I haven't quite caught up with some of the more technical coding but at least I know a lot more than I did a month ago.
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: Various NML related questions

Post by planetmaker »

3iff wrote:That's me explaining things badly...

Basically, an industry might have a reserve of raw materials. When it reaches a trigger point, I'd like to pop up a news report saying "reserves are running low" or something similar just to warn the player. I'd do a check every so often (somehow).

Is it this...?
Setting bit 8 replaces the news message with a custom message, read from register 0x100 bits 0 .. 15.

Setting bit 8 of what? and how do I set the register 0x100 bits 0 .. 15 ?

Sorry if these are basic things, I haven't quite caught up with some of the more technical coding but at least I know a lot more than I did a month ago.
Yes, setting bit 8 of the callback result enables the custom message, and then, yes, set the register 0x100. Something like (maybe you need to write it in a switch):

Code: Select all

return [STORE_TEMP(string(STR_MY_MESSAGE), 0x100), CB_RESULT_IND_PROD_DECREMENT_BY_1 | 1 << 8];
A trigger for 'too low storage' is difficult... but maybe you can work around that by checking that in the production change callback and returning an appropriate message concerning storage there. I'm not sure it'll work when you don't change production)

EDIT: corrected code sample as by 3iff's actually working code as found in his answer further down
Eddi
Tycoon
Tycoon
Posts: 8289
Joined: 17 Jan 2007 00:14

Re: Various NML related questions

Post by Eddi »

you set bit 8 with "return 0x100 | (whatever else you wanted to return)" and you set register 0x100 with STORE_TEMP
User avatar
3iff
Tycoon
Tycoon
Posts: 1105
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

Thanks both.

I have an idea in my head about how to achieve what I want to do. I'll try and piggy-back it into the monthly_prod_change code somehow. It won't be very elegant.

I was thinking that there ought to be another call available "yearly_prod_change" or something, that's called once per year. It would make this job easier.

I'll have a play around with this code and see if I can get it to work as I want.

Result!
Unnamed, 2nd Feb 1940.png
Unnamed, 2nd Feb 1940.png (87.37 KiB) Viewed 6375 times
There are a couple of issues. Because I'm calling it via CB_RESULT_IND_PROD_DECREMENT_BY_1 it is filtered by production related news. If it was in general news it might be better. I'll need to investigate.

I also need to display the industry name with the news popup but I can't yet find a way to reference that.

I've done no testing other than having the pop-up news appear. Hopefully there are no sneaky problems waiting for me.
Eddi
Tycoon
Tycoon
Posts: 8289
Joined: 17 Jan 2007 00:14

Re: Various NML related questions

Post by Eddi »

3iff wrote:it is filtered by production related news.
why exactly is this a problem? seems to me like it is the right place to be filtered.
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: Various NML related questions

Post by planetmaker »

Great that it works :)
Eddi wrote:
3iff wrote:it is filtered by production related news.
why exactly is this a problem? seems to me like it is the right place to be filtered.
However I'm with Eddi on this. All news concerning industries are inherently production-related.
User avatar
3iff
Tycoon
Tycoon
Posts: 1105
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

planetmaker wrote:Great that it works :)
Eddi wrote:
3iff wrote:it is filtered by production related news.
why exactly is this a problem? seems to me like it is the right place to be filtered.
However I'm with Eddi on this. All news concerning industries are inherently production-related.
I suppose so. The 'confusion' arises because I had "other industry production changes" filter set to off or summary. Also, it's not technically a production change but it appears so because I use the production callback to display it...but I can live with that.

For others following this, the code I needed to use was actually:
return [STORE_TEMP(string(STR_RESERVE_ANNOUNCE), 0x100), CB_RESULT_IND_PROD_DECREMENT_BY_1 | 1 << 8];

and STR_RESERVE_ANNOUNCE is an entry in the english.lng file, as in:

STR_RESERVE_ANNOUNCE :{BIGFONT}{BLACK}Industry announces reserves are likely to be exhausted within 5 years.

Use {BIGFONT} as part of that string otherwise it comes out blue, tiny and unreadable.

So, any idea how I also make a reference to the relevant industry name?
Eddi
Tycoon
Tycoon
Posts: 8289
Joined: 17 Jan 2007 00:14

Re: Various NML related questions

Post by Eddi »

3iff wrote:Also, it's not technically a production change
I disagree. "Industry runs out" is totally a production change, even if it's one that is not right now.
So, any idea how I also make a reference to the relevant industry name?
theoretically, you need access to the textstack for that, similar to callback 23 (extra purchase text)
User avatar
3iff
Tycoon
Tycoon
Posts: 1105
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

Eddi,

Theoretically, can you explain that (callback 23 and textstack) a bit more?

Ah, there's something about the textstack in the wiki (NML:Language files) but I don't know where the industry name is stored. Would it be the local town and the industry name type...which I might be able to find (STR_TOWN and the relevant string for industry type?).

I'm thinking that if I can build a string with those two details then I can add it to the annoucement string.

I'll see if that works.

WOW, I have something! Just needs a bit of work. The textstack was the clue, thanks Eddi.
I'll show a screenshot and the code once I've cleaned it up.
User avatar
3iff
Tycoon
Tycoon
Posts: 1105
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

And the nearly finished result. It just needs a newline in the right place.
Unnamed, 1st Feb 1940#1.png
Unnamed, 1st Feb 1940#1.png (82.81 KiB) Viewed 6290 times
The code.

in the relevant switch,

return [STORE_TEMP(string(STR_CONCAT2, string(STR_TOWN), string(STR_IND_COAL_MINE), string(STR_RESERVE_ANNOUNCE)), 0x100), CB_RESULT_IND_PROD_DECREMENT_BY_1 | 1 << 8];

in the lang file,

STR_CONCAT2 :{BLACK}{BIGFONT}{STRING}{NBSP}{STRING}{}{STRING}
(allows 3 strings to be displayed, town, industry type and the announcement)

STR_IND_COAL_MINE :Coal Mine
STR_RESERVE_ANNOUNCE :{BIGFONT}{BLACK}announces reserves are likely to be {RED}exhausted{BLACK} within 5 years.


It might not be pretty or elegant but it seems to work. I hadn't realised it might have been that easy.
User avatar
3iff
Tycoon
Tycoon
Posts: 1105
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

Another thing that's puzzled me. Is there any difference between these two code structures?

switch (blah blah) {
return another switch;
}

and

switch (blah blah) {
another switch;
}

Oh, another thing while I'm here. Can a newgrf install a sign on the map?
User avatar
planetmaker
OpenTTD Developer
OpenTTD Developer
Posts: 9432
Joined: 07 Nov 2007 22:44
Location: Sol d

Re: Various NML related questions

Post by planetmaker »

There (currently) is no functional difference. The form using return is the preferred one, though as it is the syntactically clearer one; the form without return might get deprecated somewhen.

NewGRFs cannot place signs.
User avatar
3iff
Tycoon
Tycoon
Posts: 1105
Joined: 21 Oct 2005 09:26
Location: Birmingham, England

Re: Various NML related questions

Post by 3iff »

Thanks. I'll update my future code to use "return another_switch;", at least for consistency.
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 1 guest