Log In  

Cart #menuitemcartdata-0 | 2021-04-02 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
1

Overview

Here are a couple of code snippets for convenience of adding options/settings that:

  • can be configured by the user via the pause menu (using MENUITEM())
    • up to five settings can be added, limited by the number of menuitems.
  • are automatically saved to & loaded from persistent cart data (0x5e00+ range, using CARTDATA())
  • supports optional callback when setting is changed
    • will also be called when first loaded, for initialization

General version

The first, generic version (tab 0) of the snippet supports:

  • settings can offer multiple choices, e.g. difficulty: {"easy","medium","hard","insane"}
  • current setting accessed as value or its 0-based index
  • each setting can be stored at any arbitrary cart data address + bitmask of contiguous bits
    • enough bits must be allocated for number of choices
    • different settings can use different bits of same byte
  • optional callback when setting is changed
  • cartdata integration is optional, can be used to create settings that aren't persisted
    • in which case an initial value can be specified instead of loading from cartdata

Usage

  • Plonk the snippet in global scope
  • in initialization code:
    • call CARTDATA()
    • add up to 5 settings, include callbacks as needed
  • in update/draw code:
    • fetch current index menuopts.name.i or value menuopts.name:v()
    • do not modify index directly! doing so will not POKE new value into cartdata nor invoke callback

Boolean-only version

The second version (tab 1) trades some functionality for token count:

  • only binary choices supported, e.g. "off"/"on", "disabled"/"enabled"
  • all options packed into one shared memory address (8 bits = up to 8 boolean flags)
  • callbacks also optional here
  • cartdata integration is compulsory

Usage

  • Plonk the snippet in global scope
  • in initialization code:
    • call CARTDATA()
    • initialize with memory address
    • add settings
  • in update/draw code:
    • fetch current value boolmenuopts.name()

Alternatively, save a few tokens by removing the function call for initialization. Strip the outermost FUNCTION..END from the snippet and just place the rest directly in your init code, after CARTDATA. Hardcode the memory address instead.

Other possible variations

The code snippets are just a starting point, and can of course be further tweaked to suit your needs.

Optimizations, e.g.

menuitem(m,d(),
 function(btn)
  o.i=(o.i+(btn&1>0 and -1 or 1))%#v -- only 1 token saved, curse operator precedence
  ...

Feature reduction, e.g.

-- variation: access current setting only by index, not value
function menuopts:add(m,n,v,a,b,c)
 self[n]=a and (@a&b)\(b&-b) or b or 0
 local function d() return n..": "..tostr(v[self[n]+1]) end
 ...

Some other ideas, depending on trade-off between required features vs token budget:

  • compulsory callback / no callback
  • remove TOSTR() from D() (=can't put bools in list of possible values)
  • generic multiple choice, but all options packed into same address
    • consider PEEK2/PEEK4 POKE2/POKE4 for more than one byte of storage
  • add ability to programmatically modify value
  • add ability to activate/inactivate whether a setting shows in the menu, to support >5 settings

.

Hope someone finds this useful!

P#89474 2021-04-02 14:30


[Please log in to post a comment]