Friday, 4 March 2011

Pesky PETSCII Prevented

I'm in the process of converting all of the pseudocode from the previous posts into real, genuine 6502 assembly, and it's going well - I may post some actual code in a few days. Simultaneously I've been thinking about the main thing that the old CHARPLOT mechanism did that the new Sprite framework doesn't do, which is support plotting of text strings to the screen - the CHARPLOT structures incorporated a feature which allowed strings to be hooked onto the object, and then processed using the same basic logic, but there's no facility to do this in the new model.

I quickly came up with a modified structure that strips-out all of the CHARPLOT object-plotting stuff (because we use the Sprite engine for that now) and optimised the string-handling feature, leaving a new STRPLOT structure that is very easy to manage, and can be passed directly to the low-level plotting logic inside the Sprite engine - so no separate string-specific drawing code is needed. This means that strings are defined as separate entities to Sprites, as you'd expect, but use Sprite-drawing features when they need to be displayed. I can now group all the games' strings together in a tight little bunch, and just refer to them when I want one drawn. Which is nice.

This then got me thinking about the technique I used to convert strings from ASCII (as they appear in the sourcecode) to PETSCII screen codes, which is what the VIC uses when drawing direct to the screen. Regular readers may recall earlier discussions on the topic, which resulted in a slick little routine which gets called when the game starts to convert all these strings in-place; the downside was that since the strings were CHARPLOT objects, the converter had to know all about how the objects were structured in order to do it's thing - essentially it had to mimic a chunk of the CHARPLOT drawing logic, but convert the characters instead of displaying them. I was never entirely happy with that.

However, I now have all the strings collected together in a simplified structure. In fact, it's so simple that I realised I could tackle the problem in a completely different way, by having the strings converted to PETSCII directly in the sourcecode, before assembling the program. The build script I'm using is very straight-forward as it just takes the name of the root source file and gives it to DASM with a few preset parameters; so there's no reason why I couldn't include a step prior to that which pre-processed a specific file, looking for ASCII strings and converting them in-place to PETSCII. By assembling the code with the strings already converted, I can then lose both the (tiny) converter routine and the (larger) structure-interpreting routine which needed to run at startup.

A matter of an hours' work in Visual Studio gave me a little app which takes a path to a 6502 source file as its' parameter, and then scans through it looking for DC.B strings. When it finds any, it applies the same code-conversion logic as the original 6502 routine did, and writes the new values back into the strings. Finally, it copies the original source file to a backup, and writes the modified copy out - this is so any INCLUDEs in other source files will point at the converted version and DASM will just build everything as normal. The caveat is that the converted file may become difficult to edit, because some PETSCII codes get interpreted as control characters when viewed in ASCII - which is why the app creates a backup, so you can always delete the converted version and copy the original back over it for editing.

It's a repeatable process - if the app finds that a backup of the source file already exists, it assumes the file has been converted and won't attempt to convert it a second time (which would scramble things rather spectacularly). Consequently I can embed the call to it in the build script and let it run on every build, but it'll only do something when it spots there's no backup for the file it's targetting.

Download link to a zipfile containing the binary over there on the right. Just drop the files into a folder somewhere, no lengthy install required - but you'll need the .NET 3.5 or 4.0 framework on your machine first, of course.

0 comments:

Post a Comment