#FOR1,100($n,I will not...)

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.