Keeping it SMPL
SkoolKit 5.1 has been released. Even though it goes without saying, I will say that copies of 5.1 are available from the download page (as usual), the Python Package Index (as usual), and the Ubuntu PPA (as usual).
Before we embark on a tour of the new features in this release, allow me to divulge a small piece of previously unrevealed history. Back in January 2012 - between 2.4 and 2.4.1 in SkoolKit time, if that’s how you prefer to measure dates - I added an item to my SkoolKit TODO list about making it possible to define a new skool macro in terms of existing skool macros without writing any Python code. At the time, it was just an idea that I hadn’t really fleshed out. And it stayed that way until fairly recently - between 5.0 and 5.1 in SkoolKit time, as it happens - when I finally decided on a scheme that would bring the idea to fruition.
Enter 5.1 with the @replace
directive, the ability to evaluate arithmetic
expressions in macro parameters, and seven new skool macros: #()
, #EVAL
,
#FOR
, #FOREACH
, #IF
, #MAP
and #PEEK
. Together they constitute the
Skool Macro Programming Language - SMPL (pronounced ‘simple’, I’ve just
decided) for short. With them you can effectively define new macros that are
shorthand for complex forms or combinations of the classic skool macros, or
that fill in gaps in their capabilities.
For example, let’s look at the good old #UDG
macro. It’s fine as far as it
goes, but one thing it has lacked all these years is the ability to specify an
address from which to collect the desired attribute byte; instead we’ve had to
hard code the attribute value into the #UDG macro’s parameter string. Now,
though, with the advent of the #PEEK macro, that has changed. Suppose the game
we’re disassembling arranges tiles in groups of nine bytes: the attribute byte
first, followed by the eight graphic bytes. Then we could create an image of
the tile at 30000 like this:
#UDG(30001,#PEEK30000)
Which is nice, but perhaps not a great improvement over hard coding the attribute value. Now suppose that we want to create images of the tiles at 30009, 30018 and so on:
#UDG(30001,#PEEK30000)
#UDG(30010,#PEEK30009)
#UDG(30019,#PEEK30018)
...
This is getting tiresome. However, the nascent SMPL programmer within you should be noticing a pattern to these macros; they are all of the form:
#UDG(addr+1,#PEEKaddr)
where addr
is the address of the tile’s attribute byte. Having identified the
pattern, we can now embody it in a @replace
directive, which replaces one
regular expression with another:
@replace=/#udg\i/#UDG(\1+1,#PEEK\1)
With this directive in place, we can now create images of the tiles with the appropriate attribute values thus:
#udg30000
#udg30009
#udg30018
...
Which, I hope you will agree, is actually starting to look somewhat handy. But
still, typing out all these #udg
macros is a pain when there are 20 of them
(say). So let’s use a #FOR
loop instead to cut down on the typing:
#FOR30000,30171,9||n|#UDG(n+1,#PEEKn)||
If you’re still not convinced of the merits of SMPL, try this control file snippet on a snapshot of Hungry Horace:
@ 28663 replace=/#maze\i/#UDGARRAY#(32#FOR(\1,\1+767)||n|;#tile||)
@ 28663 replace=/#tile/(31735+8*#PEEKn),#MAP(#PEEKn)(61,2:60,3:56)
b 28663 Maze layouts
N 28663 #maze28663(maze2)
N 29431 #maze29431(maze1)
N 30199 #maze30199(maze3)
N 30967 #maze30967(maze4)
i 31815
Now take a look at the data block at 28663, with its correctly coloured images of the mazes in the game, each one composed of 32x24 tiles. All without a single line of custom Python code in a SkoolKit extension module.
Well, I’ve done my best to showcase SMPL in this brief introduction. The rest is now up to you.
For details of the other (boring by comparison) changes in 5.1, see the changelog. But after that, go forth and define new macros.