Layman's guide on how to build Interactive Config UI's

Tutorials, How-tos and FAQs for the Titan Two device.

Re: Layman's guide on how to build Interactive Config UI's

Postby antithesis » Mon Sep 04, 2017 9:15 pm

No need to optimise it in this script, I managed to squeeze everything in. I'm just aware that there must be a better way to do it. So it's more from an educational perspective than immediate need.

If I did convert everything to fix32 I'd likely run out of pmem (already at 110) as there's a bunch of other stuff in there, so that's not an option. But I'll keep it in mind for next time :) I thought maybe piping each variable into its own array, e.g Recoil_V, Recoil_H etc would be the way to go given the variable types would then all be the same.

If I were to include the Zombies, I'd probably need 50% more bytecode. The reason I chose PvZ was it far exceeds the number of class options of other games (120+ characters) and I wanted to see how much I could cram into one script. I think I have enough room to sneak in a few more minor things like L1/L2 & R1/R2 swap to finish if off.
Last edited by antithesis on Tue Sep 05, 2017 11:28 pm, edited 1 time in total.
Official Australian retailer for Titan One, Titan Two and XIM APEX at Mod Squad
User avatar
antithesis
Colonel
Colonel
 
Posts: 1912
Joined: Sat May 28, 2016 10:45 pm

Re: Layman's guide on how to build Interactive Config UI's

Postby umpmanjoe » Mon Sep 04, 2017 11:37 pm

This is awesome, it helps me a lot with building the menu, but how do you use the information it collects.

For example - If I use your "example - aim_stabilzer" script, how could I use this to set the value which us currently 90.

how do I read the value and then use it in my mod script
Trying to teach myself how to program these scripts even though I'm old
User avatar
umpmanjoe
First Sergeant
First Sergeant
 
Posts: 45
Joined: Mon May 25, 2015 1:23 am

Re: Layman's guide on how to build Interactive Config UI's

Postby umpmanjoe » Tue Sep 05, 2017 3:46 am

I have used this to add a menu to your stabilizer for my own use but I can't figure out how to get the value to change. No matter what I slide it to, the script always reads it as 100. Can someone please help me, and explain what the change is so that I can learn

Code: Select all
#pragma METAINFO("Example - pablo stabilizer with menu", 1, 0, "pablogroup")
 
#include <ps4.gph>
 
/*******************************************************************************
<cfgdesc>
 
[Aim Stabilizer]
color       = #000060
 
 
 
MULTILINE
 
 
[Aim Stabilizer Sensitivity]
shortdesc    = This reduces the sensitivity of your aiming when shooting while ADS. By default it is set to 90, 100 means it is turned off.
byteoffset    = 4
bitsize        = 16
control        = slider
default        = 90
minimum        = 50
maximum        = 100
step        = 1
 
 
</cfgdesc>
*******************************************************************************/

 
uint16 aim_stabilizer_sensitivity;
 
init {
    pmem_load();
    aim_stabilizer_sensitivity = pmem_read(4);
}
 
 
// INPUT INITIALIZATION
//
// ----------------------------------------------------------------------------------------------------------------
 
 
 
fix32                                  NOT_USE;
bool aim_sens;
 
// USER CONFIGURABLE VARIABLES
//
// ----------------------------------------------------------------------------------------------------------------
 
// Adjust from 1-100 (set it to 100 to turn it off).
 
 
 
main {
    if(get_val(BUTTON_8) && event_active(BUTTON_15)) {
        if(aim_sens == 0) {
        aim_sens = 1;
        combo_run(RUMBLE_ON);
        combo_run(flash_on);
    }else if(aim_sens == 1) {
        aim_sens = 0;
        combo_run(RUMBLE_ON);
        combo_run(fl_off);
    }
    }
        if(aim_sens == 1) {
        sensitivity(STICK_1_Y, NOT_USE, (fix32) aim_stabilizer_sensitivity);
        sensitivity(STICK_1_X, NOT_USE, (fix32) aim_stabilizer_sensitivity);
    }
}
 
combo RUMBLE_ON {
    ffb_set(FFB_1, 66.0, 320);
    wait(0); wait(320);
}
combo flash_on {
    ColorLED('G'); wait(400);
    ColorLED('W'); wait(400);
    ColorLED('G'); wait(400);
    ColorLED('W'); wait(400);
    ColorLED('G'); wait(400);
    ColorLED('N');
}
combo fl_off {
    ColorLED('R'); wait(400);
    ColorLED('W'); wait(400);
    ColorLED('R'); wait(400);
    ColorLED('W'); wait(400);
    ColorLED('R'); wait(400);
    ColorLED('N');
    }
 
// FUNCTIONS
//
// ----------------------------------------------------------------------------------------------------------------
 
// This is a ported T1 function no longer supported by T2 (this is literally the code from T1, provided by Jefferson Koppe).
void sensitivity(uint8 i, fix32 m, fix32 s) {
   fix32 v = get_val(i);
   if(v) {
      if(m) {
         v = (v > 0.0) ? midpoint(v, m) : midpoint(v * -1.0, m) * -1.0;
      }
      if(s) {
         v = (v * s) / 100.0;
      }
      if(v > 100.0) v = 100.0;
      else if(v < -100.0) v = -100.0;
      set_val(i, v);
   }
   return;
}
fix32 midpoint(fix32 v, fix32 m) {
   if(v <= m) return((v * 50.0) / m);
   return(((50.0 * (v - m)) / (100.0 - m)) + 50.0);
}
 
 
/* <shortdesc>
<br />
This reduces the sensitivity of your right stick while you are shooting. Set the aim_stabilizer_sensitivity variable to 100 if you wish to turn this off.
</shortdesc>
 
<keywords>
aim stabilizer
</keywords> */

 
// Sets the LED color.  Definable in the declarations at the top of the script.
void ColorLED(char Color) {
    fix32 Color1, Color2, Color3, Color4;
 
    if(Color == 'B'){Color1 = 100.0;    Color2 = 0.00;    Color3 = 0.00;    Color4 = 0.00;}
    if(Color == 'R'){Color1 = 0.00;    Color2 = 100.0;    Color3 = 0.00;    Color4 = 0.00;}
    if(Color == 'G'){Color1 = 0.00;    Color2 = 0.00;    Color3 = 100.0;    Color4 = 0.00;}
    if(Color == 'P'){Color1 = 0.00;    Color2 = 0.00;    Color3 = 0.00;    Color4 = 100.0;}
    if(Color == 'C'){Color1 = 100.0;    Color2 = 0.00;    Color3 = 100.0;    Color4 = 0.00;}
    if(Color == 'A'){Color1 = 0.00;    Color2 = 100.0;    Color3 = 100.0;    Color4 = 0.00;}
    if(Color == 'W'){Color1 = 100.0;    Color2 = 100.0;    Color3 = 100.0;    Color4 = 100.0;}
    if(Color == 'N'){Color1 = 0.00;    Color2 = 0.00;    Color3 = 0.00;    Color4 = 0.00;}
 
    led_set(LED_1, Color1, 0);
    led_set(LED_2, Color2, 0);
    led_set(LED_3, Color3, 0);
    led_set(LED_4, Color4, 0);
 
 
    return;
}
Trying to teach myself how to program these scripts even though I'm old
User avatar
umpmanjoe
First Sergeant
First Sergeant
 
Posts: 45
Joined: Mon May 25, 2015 1:23 am

Re: Layman's guide on how to build Interactive Config UI's

Postby J2Kbr » Tue Sep 05, 2017 9:46 am

@umpmanjoe, as the value is 16bits length, pmem_read() should be called in its second form:
Code: Select all
pmem_read(4, &aim_stabilizer_sensitivity);
ConsoleTuner Support Team
User avatar
J2Kbr
General of the Army
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

Postby umpmanjoe » Tue Sep 05, 2017 10:39 am

J2Kbr wrote:@umpmanjoe, as the value is 16bits length, pmem_read() should be called in its second form:
Code: Select all
pmem_read(4, &aim_stabilizer_sensitivity);


So all i have to do is change that one line?
Trying to teach myself how to program these scripts even though I'm old
User avatar
umpmanjoe
First Sergeant
First Sergeant
 
Posts: 45
Joined: Mon May 25, 2015 1:23 am

Re: Layman's guide on how to build Interactive Config UI's

Postby umpmanjoe » Tue Sep 05, 2017 10:42 am

how do you know when to use each form and what are they?
Trying to teach myself how to program these scripts even though I'm old
User avatar
umpmanjoe
First Sergeant
First Sergeant
 
Posts: 45
Joined: Mon May 25, 2015 1:23 am

Re: Layman's guide on how to build Interactive Config UI's

Postby J2Kbr » Tue Sep 05, 2017 11:10 am

umpmanjoe wrote:So all i have to do is change that one line?

yes, that is correct.

umpmanjoe wrote:how do you know when to use each form and what are they?

this second form will ways work independently of the variable type (bit size). The simplified form is to use only with uint8 types and is intend for avoid variable allocation for optimization purposes.
ConsoleTuner Support Team
User avatar
J2Kbr
General of the Army
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

Postby umpmanjoe » Tue Sep 05, 2017 7:30 pm

Can someone help me. Trying to figure out this config ui stuff. I have the adjustable setting working, but how do I get the enable button to work. I want to be able to turn it off with share & L2 or with the menu toggle. I can't figure out how to do it. I keep getting an error. Any help with an explanation of what you did will be appreciated. Only way I can learn.
Code: Select all
/*******************************************************************************
<cfgdesc>
 
[Quick Scope]
color       = #000060
shortdesc   = <<<MULTILINE
 
Mod trigger - share & L2
 
 
MULTILINE
 
 
[Quick Scope]
group       = true
byteoffset  = 1
bitsize     = 1
bitoffset   = 7
control     = checkbox
default     = 0
item        = Quick Scope off/on
 
[Quick Scope Setting]
group       = true
shortdesc    = <br><b><font color="blue">Quick Scope Setting:</font></b>
byteoffset    = 2
bitsize        = 32
control        = spinbox
default        = 420
minimum        = 50
maximum        = 1000
step        = 1
 
 
</cfgdesc>
 
/*************************************************************************
                         *
**************************************************************************/

 
 
 
uint32 QuickScopeAdjustment;
 
init {
    pmem_load();
    pmem_read(2, &QuickScopeAdjustment);
    pmem_read(1, &q_scope)
}
 
bool q_scope = 0;
 
main {
 
  //quick scope
 
    if(get_val(BUTTON_2) && event_active(BUTTON_8)) {
        if(q_scope == 0) {
        q_scope = 1;
        }else if(q_scope == 1) {
        q_scope = 0;
    }
    }
    if(q_scope == 1) {
        if(event_release(BUTTON_8) && time_active(BUTTON_8) < 500) {
            combo_run(QuickScope);
        }
    }
}
 
combo QuickScope
{
    set_val(BUTTON_5, 0.0);
    set_val(BUTTON_8, 100.0);
    set_val(BUTTON_9, 100.0);
    wait(QuickScopeAdjustment);
    set_val(BUTTON_5, 100.0);
    set_val(BUTTON_8, 100.0);
    set_val(BUTTON_9, 100.0);
    wait(40);
}
 
combo sniper_breath
{
    set_val(BUTTON_9, 100.0);
    wait(10);
    set_val(BUTTON_9, 100.0);
}
Trying to teach myself how to program these scripts even though I'm old
User avatar
umpmanjoe
First Sergeant
First Sergeant
 
Posts: 45
Joined: Mon May 25, 2015 1:23 am

Re: Layman's guide on how to build Interactive Config UI's

Postby antithesis » Tue Sep 05, 2017 10:39 pm

Code: Select all
 
/*******************************************************************************
<cfgdesc>
[Quick Scope]
color       = #000060
shortdesc   = <<<MULTILINE
 
Mod trigger - share & L2
 
MULTILINE
 
[Quick Scope]
group       = true
byteoffset  = 1
bitsize     = 8
control     = checkbox
default     = 0
item        = Quick Scope off/on
 
[Quick Scope Setting]
group       = true
shortdesc    = <br><b><font color="blue">Quick Scope Setting:</font></b>
byteoffset    = 2
bitsize        = 16
control        = spinbox
default        = 420
minimum        = 50
maximum        = 1000
step        = 1
</cfgdesc>
 
/*************************************************************************
                         *
**************************************************************************/

 
bool q_scope;
uint16 QuickScopeAdjustment;
 
 
init {
    pmem_load();
    pmem_read(2, &QuickScopeAdjustment);
    q_scope = (pmem_read(1));
}
 
main {
 
  //quick scope
 
    if(get_val(BUTTON_2) && event_active(BUTTON_8)) {
            q_scope=!q_scope;}
 
    if(q_scope) {
        if(event_release(BUTTON_8) && time_active(BUTTON_8) < 500) {
            combo_run(QuickScope);
        }
    }
}
 
combo QuickScope
{
    set_val(BUTTON_5, 0.0);
    set_val(BUTTON_8, 100.0);
    set_val(BUTTON_9, 100.0);
    wait(QuickScopeAdjustment);
    set_val(BUTTON_5, 100.0);
    set_val(BUTTON_8, 100.0);
    set_val(BUTTON_9, 100.0);
    wait(40);
}
 
combo sniper_breath
{
    set_val(BUTTON_9, 100.0);
    wait(10);
    set_val(BUTTON_9, 100.0);
}
 


Variables are declared before init, which was causing the scope error.
I simplified your toggle logic, it works the same way.
q_scope was set as a bit in the cfg, but read as a byte. I made it a byte to simplify things.
QuickScopeAdjustment is a 16-bit var as you've used it, no need for 32-bit. 32-bits typically use decimal points and spinboxf in the cfgdesc.
The script now compiles, no idea if it works as I didn't test the combos.

I had trouble understanding all of the var types at first and how they applied to GPC. To make it easy on yourself, think in these terms -

bool = 0 or 1. Used for toggles.
int8 = range of -128 to 127. Not needed unless crunching code. Use "int" instead.
uint8 = range of 0 to 255. Used for IC menus. Use "int" for most other values instead.
int16 = -32768 to 32727. This is the default when using the "int" shortcut to declare variables. Suits most general purposes NOT requiring a decimal point.
uint16 = 0 to 65535. Similar, with a larger range and positive values only. Typically used for time in ms.
fix32 = Use for anything requiring a decimal point, typically when referring to stick positions, which can be positive or negative. A decimal point is ALWAYS required, e.g 0.0.

A quick guide - https://edoras.sdsu.edu/doc/matlab/tech ... /int8.html amd https://edoras.sdsu.edu/doc/matlab/tech ... uint8.html

Basically, use bool for toggles, int for time, fix32 for sticks.
For configs, 8 bits for checkboxes (toggles), 16 bits for spinboxes (time), 32 bits for spinboxf (sticks).

The reason I use spinbox instead of slider or dial is it's easier and more precise to update the values by typing than moving stuff with a finger or mouse.

Comboboxes are a bit special in that they can hold up to 255 items, but only one item is called from it. So they're 8-bit (uint8).

I try to avoid fix32 as much as possible for cfgdesc declarations as they eat up 4 blocks of the 128 pmem slots, as opposed to 2 for 16-bit and 1 for 8-bit or boolean.

Note that if anything requires a calculation, the variable types need to be the same, e.g an int16 can't be multiplied by a fix32. You can get around that by converting the int into a fix32 within the current scope, e.g within a combo, Using the (fix32) prefix. The brackets tell the script to convert the int to fix32 just in this combo. I use this a lot when converting Titan One code to Titan Two.

That about sums up my last week learning how to code ICs. I hope this helps from one old fart to another :oops:

One more request for J2K - it it possible to check for pmem clashes in the IDE? For example, two variables referring to the same pmem values. That'll save some time debugging.
Official Australian retailer for Titan One, Titan Two and XIM APEX at Mod Squad
User avatar
antithesis
Colonel
Colonel
 
Posts: 1912
Joined: Sat May 28, 2016 10:45 pm

Re: Layman's guide on how to build Interactive Config UI's

Postby antithesis » Tue Sep 05, 2017 11:42 pm

J2Kbr wrote:
antithesis wrote:I'm certain that can be condensed using arrays.

I am positive we can optimize this to reduce the bytecode size. :smile0517: I see you have different variables types (integer and real), which may limit how arrays can be used. A alternative to arrays can be the use of pointers. Please let us know the used variable types, specially for the integers, so we can try start work in the optimized code.

I've had some time to think about this.

There should be only three arrays required -

1. 8-bit vars declaring Character, Rapid-fire and Anti-recoil modes. Values range from 0 to 35 (0-255 = uint8).
2. 16-bit vars declaring Rapid-fire times. Values range from 50-10000 ms (0-65K = uint16).
3. 32-bit vars declaring Anti-recoil stick positions. Values range from -100.0 to 100.0 (decimals = fix32).

e.g.
Mode: Character = 10; HIP_RF_Mode = 1; ADS_RF_Mode = 1; HIP_AR_Mode = 1; ADS_AR_Mode = 1;
Time: HIP_RapidHold = 50; HIP_RapidWait = 50; ADS_AutoHold = 5000; ADS_AutoWait = 1500;
Position: HIP_Recoil_V = 24.5; HIP_Recoil_H = -7.5; ADS_Recoil_V = 26.0; ADS_Recoil_H = -0.0;

One potential complication is Time could refer to HIP_RapidHold, ADS_RapidHold, HIP_AutoHold, ADS_AutoHold, HIP_SemiHold and ADS_SemiHold, depending on the value of HIP_RF_Mode and ADS_RF_Mode. I guess I just need to add all 6 to the array and assign those with no values to 0.

I'll poke around Scachi's code to see if I can nut it out, but any help would be appreciated. As I've coded it, this stuff eats up around half of the bytecode, which is really inefficient.

Also, can you explain pointers and how they might be used? Is that "switch" and "case"?
Official Australian retailer for Titan One, Titan Two and XIM APEX at Mod Squad
User avatar
antithesis
Colonel
Colonel
 
Posts: 1912
Joined: Sat May 28, 2016 10:45 pm

PreviousNext

Return to Tutorials and FAQs

Who is online

Users browsing this forum: No registered users and 61 guests

cron