[nfo] what larks with registers

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

Moderator: Graphics Moderators

Post Reply
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5658
Joined: 31 Mar 2007 14:23
Location: Lost in Music

[nfo] what larks with registers

Post by andythenorth »

Ah what fun. I want to stick a constant value into persistent storage for use by the production callback.
I then want to get that value and push it onto the text stack (for debug initially, then later will be for player info)

Here's something that doesn't actually crash the game or make renum sulk, but stubbornly displays 0 in the industry window.

Code: Select all

// assume action 0 is all tickety-boo and works

// action 2s
-1 * 0 02 0A B0 //store a production for each cargo (65,535)
      89 // using type 89 because register IDs are better specified as double words
        1A 20  \dxFFFFFFFF // create a value (constant 1A anded (20) with following bytes) 
        10  1A 00 \dx01 // store in persistent storage
       01
         A0 00  00 00 00 00  00 00 00 00
       A0 00

-1 * 0 02 0A CC //store something to register, return text ID  
    89 // 
      7C 01 20  \dxFFFFFFFF // get a value from persistent storage 
      0E 1A 00 \dx100 // store in register
    \b1 //range (stay out of the nvar=0 bear pit by checking one range, but returning same for both)
       STR_INFO_DEBUG 80  00 00 00 00  00 00 00 00
     STR_INFO_DEBUG 80 //default

// assume action 3 and varaction 2 for handling industry text cb is good and fine and works

------
// text code
-1 * 0 04 0A LANG_ID2 01 STR_INFO_DEBUG D0 "\94DEBUG \0DCargo 1 prod ratio: \7C \0D" 00


Current Result: shows something Jim, but not what we expected (65,535 should be there, right?)
what_larks.png
what_larks.png (35.89 KiB) Viewed 3537 times
Either: (1) failing to put the right value in a register
(2) failing to read the register correctly / getting 0 as the default value of the register
(3) doing something stupid with bits that makes my result 0.

What larks :) Any clues?
frosch
OpenTTD Developer
OpenTTD Developer
Posts: 988
Joined: 20 Dec 2006 13:31
Location: Aschaffenburg

Re: [nfo] what larks with registers

Post by frosch »

I cannot see anything wrong in that part. It should display "-1" (65535 would be unsigned word).

So, are you sure that the assigning advaction2 is executed. And in which CB do you assign it?
⢇⡸⢸⠢⡇⡇⢎⡁⢎⡱⢸⡱⢸⣭⠀⢸⢜⢸⢸⣀⢸⣀⢸⣭⢸⡱⠀⢰⠭⡆⣫⠰⣉⢸⢸⠀⢰⠭⡆⡯⡆⢹⠁⠀⢐⠰⡁
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5658
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: [nfo] what larks with registers

Post by andythenorth »

frosch wrote:In which CB do you assign it?
In a production callback which was not enabled in action 0, it turns out :evil:

I have about 25 secondary industries, I had turned on the production callback in every single one *except* the one I decided to start coding registers in. _sigh_

Still, this is a small victory...of sorts :)
victory_sort_of.png
victory_sort_of.png (36.21 KiB) Viewed 3492 times
I don't actually want -1, I want 65,535, but that can be sorted out. I also need to pack two more values into the text stack (for the other cargos), reading the wiki again makes me a bit concerned about how I do that, but I'm sure it will be easier after a nice bit of sleep.

Putting register values in the industry window makes me feel much better about debugging :)

Thanks frosch, once again you rescue my code :bow:
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5658
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: [nfo] what larks with registers

Post by andythenorth »

Another day, another small victory:
another_victory_sort_of.png
another_victory_sort_of.png (39.27 KiB) Viewed 3473 times
3 values successfully pushed in persistent storage, 3 values fetched from persistent storage and pushed onto the text stack. 3 values printed out.

I am pushing 3 dwords onto the stack (each value completely fills a register in the range 101-103). I then use \7B to print them as dwords.

That works, but seems like this might be a bit wasteful on registers, I only need words, but I haven't figured out how to pack more than one value into a register yet. I guess it's some kind of AND with bit shift?

Also, so these are signed negative because I'm ANDing them with 1A which is a constant -1? How do I make them positive? Multiply by 1A? EDIT: no longer an issue, I've changed the escapes to set the values directly as dec not hex.

cheers,

Andy
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5658
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: [nfo] what larks with registers

Post by andythenorth »

All the code for this industry (but not the tiles) :)

Code: Select all

//Industry definition

//Action 0
-1 * 0 00 0A \b26 01 IND_MACHINESHOP //-1 * 0 00 0A <num-props> 01 <id>
	08 IND_NULL //reuse original industry with this here ID
	0A 02 //number of industry layouts
		\d204 //sum(size of layout definition +2 for termination)
		//layout:
			00 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			00 01 FE TILE_MACHINESHOP_1 00
			00 02 FE TILE_MACHINESHOP_1 00
			01 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			01 01 FE TILE_MACHINESHOP_1 00
			01 02 FE TILE_MACHINESHOP_1 00
			02 01 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			02 02 FE TILE_MACHINESHOP_1 00
			03 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			03 01 FE TILE_MACHINESHOP_1 00
			03 02 FE TILE_MACHINESHOP_1 00
			04 01 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			04 02 FE TILE_MACHINESHOP_1 00
			05 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			05 01 FE TILE_MACHINESHOP_1 00
			06 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			06 01 FE TILE_MACHINESHOP_1 00
			07 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			07 01 FE TILE_MACHINESHOP_1 00
			02 00 FE TILE_GENERIC_CONCRETE 00
			04 00 FE TILE_GENERIC_CONCRETE 00
			05 02 FE TILE_GENERIC_CONCRETE 00
		00 80 //terminate layout definition
		//layout:
			00 01 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			00 02 FE TILE_MACHINESHOP_1 00
			01 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			01 01 FE TILE_MACHINESHOP_1 00
			01 02 FE TILE_MACHINESHOP_1 00
			02 01 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			02 02 FE TILE_MACHINESHOP_1 00
			03 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			03 01 FE TILE_MACHINESHOP_1 00
			03 02 FE TILE_MACHINESHOP_1 00
			04 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			04 01 FE TILE_MACHINESHOP_1 00
			05 00 FE TILE_MACHINESHOP_1 00 //xoffs yoffs FE newtile(W)
			05 01 FE TILE_MACHINESHOP_1 00
			00 00 FE TILE_GENERIC_CONCRETE 00
			02 00 FE TILE_GENERIC_CONCRETE 00
			04 02 FE TILE_GENERIC_CONCRETE 00
			05 02 FE TILE_GENERIC_CONCRETE 00
		00 80 //terminate layout definition
	0B 04 //production flags 1h=extractive, 2h=organic, 4h=processing
	0C STR_IND_CLOSE_GENERIC //industry closure message
	0D STR_IND_PRODINCR_GENERIC //production increase message
	0E STR_IND_PRODDECR_GENERIC //production decrease message
	1B STR_IND_NEW_GENERIC //new industry message
	1F STR_IND_MACHINESHOP //industry name
	10 CARGO_FARMSUPPLIES CARGO_ENGINEERINGSUPPLIES //production cargo types (word; fill unused with FFh)
	11 CARGO_STEEL CARGO_ALUMINIUM CARGO_PARTS FF //acceptance cargo types (dword; fill unused with FFh)
	12 \b0 //production multiplier cargo 1
	13 \b0 //production multiplier cargo 2
	1C \w115 \w115 //input cargo 1 multiplier (dword M1 M2; output_typen = X*Mn/256)
	1D \w115 \w115 //input cargo 2 multiplier
	1E \w115 \w115 //input cargo 3 multiplier
	14 \b05 //minimal cargo distribution amount
	16 FF FF FF //conflicting industry types (3*byte; ID+80h; FF to disable)
	17 \b5 //probability in random game
	18 \b3 //probability during gameplay
	20 FF FF FF BF //prospecting success chance (dword; FFFFFFFFh=100%)
	0F \b255 //fund cost multiplier (byte)
	19 30 //map colour (byte; using indexes from dos palette)
	23 \d0  //descruction cost multiplier (dword; default: 0)
	1A \d0 //special industry flag (dword)
	21 84 //callback flags
	22 01  //callback flags
	

//No action 1 for industries, as graphics are defined by the industry-tile feature.

//Action 2 industry special features


//3 input cargos
//2 output cargos
//1:1 production ratio input:output 
//50:50 distribution to output cargos C1 output = 50% total input, C1 output = 50% total input


//Production callback 
-1 * 0 02 0A A0 //-1 * 0 0A <set-id>
	00 //version
	FF FF  FF FF  FF FF //<subtract-in-1..3>
	FF FF  FF FF //<add-out-1..2>
	00 //don't repeat

-1 * 0 02 0A B2 //store production ratios for each cargo
      89 // using type 89 because register IDs are better specified as double words
        1A 20  \d200 // create a value (constant 1A anded (20) with following bytes) 
        10  1A 00 \dx03 // store in persistent storage
       01
         A0 00  00 00 00 00  00 00 00 00
       A0 00     
       
-1 * 0 02 0A B1 //store production ratios for each cargo
      89 // using type 89 because register IDs are better specified as double words
        1A 20  \d400 // create a value (constant 1A anded (20) with following bytes) 
        10  1A 00 \dx02 // store in persistent storage
       01
         B2 00  00 00 00 00  00 00 00 00
       B2 00
       
-1 * 0 02 0A B0 //store production ratios for each cargo
      89 // using type 89 because register IDs are better specified as double words
        1A 20  \d800 // create a value (constant 1A anded (20) with following bytes) 
        10  1A 00 \dx01 // store in persistent storage
       01
         B1 00  00 00 00 00  00 00 00 00
       B1 00


-1 * 0 02 0A CC //store something to register, return text ID  
    89 // 
      7C 03 20  \dxFFFFFFFF // get a value from persistent storage 
      0E 1A 00 \dx100 // store in register
    \b1 //range (stay out of the nvar=0 bear pit by checking one range, but returning same for both)
       STR_INFO_DEBUG 80  00 00 00 00  00 00 00 00
     STR_INFO_DEBUG 80 //default

-1 * 0 02 0A CB //store something to register, return text ID  
    89 // 
      7C 02 20  \dxFFFFFFFF // get a value from persistent storage 
      0E 1A 00 \dx101 // store in register
    \b1 //range (stay out of the nvar=0 bear pit by checking one range, but returning same for both)
       CC 00  00 00 00 00  00 00 00 00
     CC 00 //default

-1 * 0 02 0A CA //store something to register, return text ID  
    89 // 
      7C 01 20  \dxFFFFFFFF // get a value from persistent storage 
      0E 1A 00 \dx102 // store in register
    \b1 //range (stay out of the nvar=0 bear pit by checking one range, but returning same for both)
       CB 00  00 00 00 00  00 00 00 00
     CB 00 //default

//Callback 38 display additional text in fund window
-1 * 0 02 0A C0 //-1 * 0 0A <set-id>
	85 0C //<type> <variable> word-access callback
	00 FF FF //no shift, no mask
	\b2 //number of ranges to check
	  STR_INFO_MACHINESHOP 80   38 00   38 00 //return text-ID D0xx if cb 38 (fund window)
	  CA 00   3A 00   3A 00 // cb 3A (industry window)
	B0 00 //default


//Industry action 3 attach varaction2 chain to industry
-1 * 0 03 0A 01 IND_MACHINESHOP 00 \wxC0 //-1 * 0 03 09 <n-ids> <id> 00 <def-cid>
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5602
Joined: 13 Sep 2004 13:21
Location: The Moon

Re: [nfo] what larks with registers

Post by PikkaBird »

andythenorth wrote:That works, but seems like this might be a bit wasteful on registers, I only need words, but I haven't figured out how to pack more than one value into a register yet. I guess it's some kind of AND with bit shift?
Sure, you can read the words from the registers seperately. Don't worry about being "wasteful" though, using 4 out of a possible 256 :) (remember, the temporary registers are action-2-chain specific).
andythenorth wrote:Also, so these are signed negative because I'm ANDing them with 1A which is a constant -1? How do I make them positive? Multiply by 1A?
If it's a signed integer, the most significant bit will decide whether it's positive or negative. If you're reading 4 bytes, FFFFFFFF is -1; 65,535 is 0000FFFF, and the largest positive signed number you can have is 7FFFFFFF.
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5658
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: [nfo] what larks with registers

Post by andythenorth »

Another small win:
all_your_register_belong_to_us.png
all_your_register_belong_to_us.png (39.55 KiB) Viewed 3457 times
But why do I need to know cargo waiting you ask? Isn't it already in the window? Well I need to put that in a register and print out it's value to check I've done it right.

UPDATE: and here's something vaguely like a debugger. Works unless the code that provides the debug info is buggy. If you follow.
oh_what_a_lark.png
oh_what_a_lark.png (48.22 KiB) Viewed 3451 times
For those who've been following IRC, I didn't manage to get two words into a register, and right now I don't seem to need it. Pikka gave me pseudo code, and I'm sure I'd be a better person if I learnt how to use it, but I'm baffled by the operators I need :)

Code: Select all

Pikka: okay, if you have 0000aaaa and 0000bbbb and you want to make aaaabbbb
[09:28] andythenorth: yup
[09:29] Pikka: A, shift 0 AND 0000FFFF, add (operator 00) b shift 16 AND FFFF0000.
[09:29] Pikka: sorry, that's the wrong way round, that will give you bbbbaaaa, but you know what I mean.
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5658
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: [nfo] what larks with registers

Post by andythenorth »

Total epic win: loads of debug information; packs words into dwords to get more info onto the text stack.
epic_win.png
epic_win.png (40.59 KiB) Viewed 3418 times
That window now shows the first FIRS processing industry with completed code :)
User avatar
PikkaBird
Graphics Moderator
Graphics Moderator
Posts: 5602
Joined: 13 Sep 2004 13:21
Location: The Moon

Re: [nfo] what larks with registers

Post by PikkaBird »

andythenorth wrote:For those who've been following IRC, I didn't manage to get two words into a register, and right now I don't seem to need it. Pikka gave me pseudo code, and I'm sure I'd be a better person if I learnt how to use it, but I'm baffled by the operators I need :)
Looks like you've got it. :) Something like

Code: Select all

1 * 1      02 0A 00 89 7D 0A 20 FF FF 00 00
                   \2+ 7D 0B 30 00 00 FF FF
                   \2s 1A    00 \dx101
01 00 00 \d0 \d0 00 00
?
User avatar
andythenorth
Tycoon
Tycoon
Posts: 5658
Joined: 31 Mar 2007 14:23
Location: Lost in Music

Re: [nfo] what larks with registers

Post by andythenorth »

frosch gave me the advanced parts of this code :) This reads persistent storage registers 01h and 03h (words) and puts them into register 100h for the text stack.

Code: Select all

-1 * 0 02 0A CA //store two values to text stack for debugging
    89
      7c 02 20 \dxffff  // get value from storage 02h
      \2ror 1a 20 \d16 // rotate value right
      \2| 7c 03 20 \dxffff  // OR with value from storage 03h
      \2sto 1a 00 \dx100 // store in register 100h
    \b1 //range (stay out of the nvar=0 bear pit by checking one range, but returning same for both)
       CB 00  00 00 00 00  00 00 00 00 
     CB 00 //default
Post Reply

Return to “NewGRF Technical Discussions”

Who is online

Users browsing this forum: No registered users and 8 guests