Layman's guide on how to build Interactive Config UI's
Layman's guide on how to build Interactive Config UI's
I didn't have a clue what I was doing at first so I figured I'd put together a guide for any people who, like me, aren't technically savvy. I've used non-technical language where I can, and I've focused on memory management as this was the part that confused me the most at first.
Ok let's start.
Firstly, here's an example of what an interactive config UI looks like. It allows users of your script to configure variables without messing with the main code:
![Image](https://i.imgur.com/YskDMhe.jpg)
Anyway, the first thing you need to know is when building Interactive Configs, you need to work at quite a low level when it comes to managing memory.
Imagine that the Titan Two has a bunch of memory blocks, like this:
[block 1-1] [block 1-2] [block 1-3] [block 1-4] [block 1-5] [block 1-6] [block 1-7] [block 1-8]
[block 2-1] [block 2-2] [block 2-3] [block 2-4] [block 2-5] [block 2-6] [block 2-7] [block 2-8]
[etc..]
Notice that each collection of blocks stores 8 pieces of data each.
When a user interacts with the UI, these interactions need to be recorded in one or more of the above blocks of memory.
So in my screenshot, if they click the "Enable" checkbox, we can store this in say, block [1-1].
This is a simplified version of the code I used:
Because the checkbox is binary (it's either checked or not checked), it only takes up one block. So the above code basically says - "when a user selects the checkbox, store their selection in the 1st collection of blocks...store it in the very 1st block...and the data I need to store is only 1 block in size".
This means that in theory, blocks [1-2] onwards are empty for you to store something else. However to make things simple for myself, I have used the next set of blocks, starting from [2-1], as you can see here:
Now as you can see above, because this is a slider and not a simple checkbox, I need 16 blocks to store this data...not 1.
What this means is the third control (called "Aim Stabilizer Senstivity" in my screenshot above) can't fit into block [3-1], because each collection of blocks can only store 8 pieces of data, and I need 16. Because my second control was 16 blocks in size, it consumed all the memory available in collections [2] and [3]. So you'll notice the third control starts on block [4-1] NOT [3-1], as you can see here:
If you have made an error, the compiler will not warn you, so you need to make sure you have done it right. If you are not sure, just count all the memory blocks you are using to make sure you haven't overlapped any. In my experience this is THE most common source of bugs, so if you can't get it working check this first.
And here's my expanded example (notice that "first" in programming speak is actually 0, not 1...I didn't mention this above as I didn't want to confuse you before you've had a chance to get your head around the concept):
NOTE: You'll notice all the UI stuff is commented out. When I first saw this I was a bit confused and thought it was a mistake. No, this is actually how it's done!
ADVANCED STUFF:
Dropdown menus (which we call a "combobox") are a tiny bit trickier, but here's a quick guide on how they work.
Firstly, here's a screenshot of what I'm talking about:
![Image](https://i.imgur.com/JnAQ3v3.jpg)
Each value you want listed in the dropdown menu is assigned a number, with the first one, which is 0, being "off". You then use code to figure out which value the user has configured:
Anyway I don't know if I've done a particularly good job explaining this, but hopefully someone out there might find this of value...
Ok let's start.
Firstly, here's an example of what an interactive config UI looks like. It allows users of your script to configure variables without messing with the main code:
![Image](https://i.imgur.com/YskDMhe.jpg)
Anyway, the first thing you need to know is when building Interactive Configs, you need to work at quite a low level when it comes to managing memory.
Imagine that the Titan Two has a bunch of memory blocks, like this:
[block 1-1] [block 1-2] [block 1-3] [block 1-4] [block 1-5] [block 1-6] [block 1-7] [block 1-8]
[block 2-1] [block 2-2] [block 2-3] [block 2-4] [block 2-5] [block 2-6] [block 2-7] [block 2-8]
[etc..]
Notice that each collection of blocks stores 8 pieces of data each.
When a user interacts with the UI, these interactions need to be recorded in one or more of the above blocks of memory.
So in my screenshot, if they click the "Enable" checkbox, we can store this in say, block [1-1].
This is a simplified version of the code I used:
- Code: Select all
[Toggle Lean - Reload Cancel]
byteoffset = 1
bitsize = 1
bitoffset = 1
control = checkbox
Because the checkbox is binary (it's either checked or not checked), it only takes up one block. So the above code basically says - "when a user selects the checkbox, store their selection in the 1st collection of blocks...store it in the very 1st block...and the data I need to store is only 1 block in size".
This means that in theory, blocks [1-2] onwards are empty for you to store something else. However to make things simple for myself, I have used the next set of blocks, starting from [2-1], as you can see here:
- Code: Select all
[ADS Sensitivity]
byteoffset = 2
bitsize = 16
control = slider
Now as you can see above, because this is a slider and not a simple checkbox, I need 16 blocks to store this data...not 1.
What this means is the third control (called "Aim Stabilizer Senstivity" in my screenshot above) can't fit into block [3-1], because each collection of blocks can only store 8 pieces of data, and I need 16. Because my second control was 16 blocks in size, it consumed all the memory available in collections [2] and [3]. So you'll notice the third control starts on block [4-1] NOT [3-1], as you can see here:
- Code: Select all
[Aim Stabilizer Sensitivity]
byteoffset = 4
bitsize = 16
control = slider
If you have made an error, the compiler will not warn you, so you need to make sure you have done it right. If you are not sure, just count all the memory blocks you are using to make sure you haven't overlapped any. In my experience this is THE most common source of bugs, so if you can't get it working check this first.
And here's my expanded example (notice that "first" in programming speak is actually 0, not 1...I didn't mention this above as I didn't want to confuse you before you've had a chance to get your head around the concept):
- Code: Select all
init {
pmem_load();
pmem_read(1, &toggle_lean_reload_switch);
pmem_read(2, &xim_ads_sensitivity);
pmem_read(4, &aim_stabilizer_sensitivity);
}
bool toggle_lean_reload_switch = FALSE;
int xim_ads_sensitivity = 84;
int aim_stabilizer_sensitivity = 90;
/*[Toggle Lean - Reload Cancel]
shortdesc = Enable this if you would like reloading to cancel Toggle Lean. If you use double tap Sprint to reload (mainly Nav users), you should enable this as the reload animation can block weapon swapping from executing when you have 0 bullets left. This has left me dangerously exposed a number of times. Keyboard and standard controller users can disable this.
byteoffset = 1
bitsize = 1
bitoffset = 0
control = checkbox
default = 1
item = Enable
[ADS Sensitivity]
shortdesc = For XIM4 users, this replaces your XIM4 ADS sensitivity setting. If you have Toggle Lean turned on, your XIM4 ADS sensitivity needs to be set to the same value as your Hip sensitivity. If you want to change your ADS sensitivity (as most people prefer it to be lower than Hip sensitivity), it should be managed from here instead of your XIM4.
byteoffset = 2
bitsize = 16
control = slider
default = 84
minimum = 70
maximum = 100
step = 1
[Aim Stabilizer Sensitivity]
shortdesc = This reduces the sensitivity of your aiming when shooting while ADS. By default it is set to 100, which effectively means it is turned off.
byteoffset = 4
bitsize = 16
control = slider
default = 100
minimum = 70
maximum = 100
step = 1
*/
NOTE: You'll notice all the UI stuff is commented out. When I first saw this I was a bit confused and thought it was a mistake. No, this is actually how it's done!
ADVANCED STUFF:
Dropdown menus (which we call a "combobox") are a tiny bit trickier, but here's a quick guide on how they work.
Firstly, here's a screenshot of what I'm talking about:
![Image](https://i.imgur.com/JnAQ3v3.jpg)
Each value you want listed in the dropdown menu is assigned a number, with the first one, which is 0, being "off". You then use code to figure out which value the user has configured:
- Code: Select all
init {
sniper_mode_toggle_switch = pmem_read(11);
}
bool sniper_mode_toggle_switch = TRUE;
main {
// Hold mode.
if(sniper_mode_toggle_switch == 1) {
// code here
}
// Toggle mode.
if(sniper_mode_toggle_switch == 2) {
// code here
}
}
/*[Sniper Mode]
shortdesc = This further reduces the sensitivity of your aiming when you are holding the Vault button while ADS. Think of this as a built-in DPI changer. Be careful not to set this too low as this stacks on top of the Aim Stabilizer sensitivity. To activate Sniper Mode, you have the choice of toggling instead of holding the Vault button.
byteoffset = 11
bitsize = 8
control = combobox
default = 0
item = Off //T2 will consider this #0 (or "turn it off")
item = Hold //T2 will consider this #1, see code example above
item = Toggle //And because this is the third in my list of items, T2 will consider this #2
/*
Anyway I don't know if I've done a particularly good job explaining this, but hopefully someone out there might find this of value...
Last edited by pablosscripts on Wed Nov 09, 2016 11:21 am, edited 17 times in total.
Setup: XIM Apex, T2, K780 keyboard, G Pro Wireless mouse, SteelSeries 4HD pad, DXRacer armrest, LucidSound LS30 headset, Netduma router, Ubiquiti UniFi AP LR
My R6 script: https://youtu.be/x-9NtxyySVM
My R6 script: https://youtu.be/x-9NtxyySVM
-
pablosscripts - Brigadier General
- Posts: 1976
- Joined: Tue Nov 24, 2015 6:27 am
Re: Layman's guide on how to build Interactive Config UI's
Great explanation!!
sticking this post.
![smile0101 :)](./images/smilies/smile0101.gif)
ConsoleTuner Support Team
-
J2Kbr - General of the Army
- Posts: 20323
- Joined: Tue Mar 18, 2014 1:39 pm
Re: Layman's guide on how to build Interactive Config UI's
Checking your script more carefully I noticed you have a redundant code that is not needed:
You can remove these lines. Quick explanation:
pmem_read with only one argument returns an uint8 type. If you have variables with any different type, such as int8, int16, uint16, int32, fix32, etc the use pmem_read with two arguments is required, as the compiler will check the variable type to correctly copy the value from the persistent memory based on the index (1st argument) and type size from the second argument.
As general rule: (1) use pmem_read with two arguments to store the value in an variable; (2) use pmem_read with one argument to check an uint8 value from the persistent memory in conditionals.
- Code: Select all
toggle_lean_reload_switch = pmem_read(1);
xim_ads_sensitivity = pmem_read(2);
aim_stabilizer_sensitivity = pmem_read(4);
You can remove these lines. Quick explanation:
pmem_read with only one argument returns an uint8 type. If you have variables with any different type, such as int8, int16, uint16, int32, fix32, etc the use pmem_read with two arguments is required, as the compiler will check the variable type to correctly copy the value from the persistent memory based on the index (1st argument) and type size from the second argument.
As general rule: (1) use pmem_read with two arguments to store the value in an variable; (2) use pmem_read with one argument to check an uint8 value from the persistent memory in conditionals.
ConsoleTuner Support Team
-
J2Kbr - General of the Army
- Posts: 20323
- Joined: Tue Mar 18, 2014 1:39 pm
Re: Layman's guide on how to build Interactive Config UI's
Great thanks! I've updated the example. I've also added a section at the bottom about comboboxes, under the title "ADVANCED STUFF".
Setup: XIM Apex, T2, K780 keyboard, G Pro Wireless mouse, SteelSeries 4HD pad, DXRacer armrest, LucidSound LS30 headset, Netduma router, Ubiquiti UniFi AP LR
My R6 script: https://youtu.be/x-9NtxyySVM
My R6 script: https://youtu.be/x-9NtxyySVM
-
pablosscripts - Brigadier General
- Posts: 1976
- Joined: Tue Nov 24, 2015 6:27 am
Re: Layman's guide on how to build Interactive Config UI's
Lovely jubbly! That'll save me some grief.
On the subject of pmem, I'm assuming it's more or less the same thing as SPVAR, is that right?
On T1, we had 16 SPVARs per script. Is there a limit to the number of pmem "slots" we can access on T2?
On T1, the values we could store in SPVARs were 0-124-ish (no negatives allowed?). Is it the same for pmem on T2?
My reason for asking is I'm considering adding adjustable rapid-fire and anti-recoil for Primary HIP, Primary ADS, Secondary HIP, Secondary ADS, Tertiary (e.g Heavy or Sidearms) HIP and Tertiary ADS. That equates to 30 values to be stored, which isn't possible on a T1.
If pmem is still limited, am I better off looking at storing these values into a dataset of 5 values for each viewpoint (RF HIP, RF ADS, AR Left, AR Right, AR Vert)? Any examples of how to approach that problem?
Will Interactive UI's allow for negative and positive values e.g -100 for Left AR, +100 for Right AR?
So many questions...
On the subject of pmem, I'm assuming it's more or less the same thing as SPVAR, is that right?
On T1, we had 16 SPVARs per script. Is there a limit to the number of pmem "slots" we can access on T2?
On T1, the values we could store in SPVARs were 0-124-ish (no negatives allowed?). Is it the same for pmem on T2?
My reason for asking is I'm considering adding adjustable rapid-fire and anti-recoil for Primary HIP, Primary ADS, Secondary HIP, Secondary ADS, Tertiary (e.g Heavy or Sidearms) HIP and Tertiary ADS. That equates to 30 values to be stored, which isn't possible on a T1.
If pmem is still limited, am I better off looking at storing these values into a dataset of 5 values for each viewpoint (RF HIP, RF ADS, AR Left, AR Right, AR Vert)? Any examples of how to approach that problem?
Will Interactive UI's allow for negative and positive values e.g -100 for Left AR, +100 for Right AR?
So many questions...
-
antithesis - Colonel
- Posts: 1912
- Joined: Sat May 28, 2016 10:45 pm
Re: Layman's guide on how to build Interactive Config UI's
The PMEM is similar to SPVAR in the sense you can store values, most notable for user's configuration of scripts/gamepacks.
On Titan One, as you mentioned, there are 16 int values that can be stored. On the Titan Two there is an array of 128 bytes that can be freely used, meaning, as far you don't exceed the 128 bytes is possible store much configurations than the Titan One. Storing 30 values as you need is totally possible using PMEM. Negative values are allowed, no limitation on this matter.
On Titan One, as you mentioned, there are 16 int values that can be stored. On the Titan Two there is an array of 128 bytes that can be freely used, meaning, as far you don't exceed the 128 bytes is possible store much configurations than the Titan One. Storing 30 values as you need is totally possible using PMEM. Negative values are allowed, no limitation on this matter.
ConsoleTuner Support Team
-
J2Kbr - General of the Army
- Posts: 20323
- Joined: Tue Mar 18, 2014 1:39 pm
Re: Layman's guide on how to build Interactive Config UI's
Hi, i try to figure out how UI are working. I took the example from this thread but i´m not able to open the config menu, neither it will be shown when i drop the file into a memory slot.
Can someone give me an advice?
Can someone give me an advice?
- Code: Select all
bool sniper_mode_toggle_switch = TRUE;
init {
sniper_mode_toggle_switch = pmem_read(11);
}
main {
// Hold mode.
if(sniper_mode_toggle_switch == 1) {
// code here
}
// Toggle mode.
if(sniper_mode_toggle_switch == 2) {
// code here
}
}
/*[Sniper Mode]
shortdesc = This further reduces the sensitivity of your aiming when you are holding the Vault button while ADS. Think of this as a built-in DPI changer. Be careful not to set this too low as this stacks on top of the Aim Stabilizer sensitivity. To activate Sniper Mode, you have the choice of toggling instead of holding the Vault button.
byteoffset = 11
bitsize = 8
control = combobox
default = 0
item = Off //T2 will consider this #0 (or "turn it off")
item = Hold //T2 will consider this #1, see code example above
item = Toggle //And because this is the third in my list of items, T2 will consider this #2
/*
-
monty34 - Command Sergeant Major
- Posts: 165
- Joined: Wed Jun 28, 2017 7:25 pm
Re: Layman's guide on how to build Interactive Config UI's
The code you posted is missing the tags to open and close the configuration descriptor section (<cfgdesc></cfgdesc>), please update your code to:
Also, with the code opened on Gtuner IV, you can press F9 to preview the configuration without the need of drop it on a memory slot.![smile0103 :joia:](./images/smilies/smile0103.gif)
- Code: Select all
bool sniper_mode_toggle_switch = TRUE;
init {
sniper_mode_toggle_switch = pmem_read(11);
}
main {
// Hold mode.
if(sniper_mode_toggle_switch == 1) {
// code here
}
// Toggle mode.
if(sniper_mode_toggle_switch == 2) {
// code here
}
}
/*
<cfgdesc>
[Sniper Mode]
shortdesc = This further reduces the sensitivity of your aiming when you are holding the Vault button while ADS. Think of this as a built-in DPI changer. Be careful not to set this too low as this stacks on top of the Aim Stabilizer sensitivity. To activate Sniper Mode, you have the choice of toggling instead of holding the Vault button.
byteoffset = 11
bitsize = 8
control = combobox
default = 0
item = Off //T2 will consider this #0 (or "turn it off")
item = Hold //T2 will consider this #1, see code example above
item = Toggle //And because this is the third in my list of items, T2 will consider this #2
</cfgdesc>
/*
Also, with the code opened on Gtuner IV, you can press F9 to preview the configuration without the need of drop it on a memory slot.
![smile0103 :joia:](./images/smilies/smile0103.gif)
ConsoleTuner Support Team
-
J2Kbr - General of the Army
- Posts: 20323
- Joined: Tue Mar 18, 2014 1:39 pm
Re: Layman's guide on how to build Interactive Config UI's
Perfect, thanks!
After choosing an option via the UI dropdown, do i need to save the value via the pmem_write or is it done automaticly?
After choosing an option via the UI dropdown, do i need to save the value via the pmem_write or is it done automaticly?
-
monty34 - Command Sergeant Major
- Posts: 165
- Joined: Wed Jun 28, 2017 7:25 pm
Who is online
Users browsing this forum: No registered users and 39 guests