Jump to content
Karl G

Handy Scripts and Utilities

Recommended Posts

I was thinking it might be nice to have a topic where people can share scripts and utilities they use in their projects that might also be useful to others.

 

On that topic, what do the rest of you use as a utility language for data generations/manipulation and the like? I had been using Bash (UNIX shell script) and C, but I forced myself recently to learn some Python, which I have found immensely useful for these kinds of purposes.

 

Anyway, here is a script I made to generate image data for text strings, using the "Glacier Belle" font used on the PlusCart. I'm sharing it in case it's useful to anyone else who needs to quickly generate text image data.

 

To use, set the text_length variable to the desired length (defaults to 12), then run it with a quoted string with the correct number of characters, and a table base name for the generated data.  E.g.:

 

./gentext.py 'Hello World!' hello_world
hello_world0
    .byte %00000000
    .byte %00000000
    .byte %01010011
    .byte %01010111
    .byte %01010100
    .byte %01010110
    .byte %01110111
    .byte %01110101
    .byte %01010111
    .byte %01010010
    .byte %01010000
    .byte %01010000

hello_world1
    .byte %00000000
    .byte %00000000
    .byte %00100010
    .byte %00100010
    .byte %00100010
    .byte %00100010
    .byte %00100010
    .byte %00100010
    .byte %00100010
    .byte %00100010
    .byte %01100110
    .byte %01100110

hello_world2
    .byte %00000000
    .byte %00000000
    .byte %00100000
    .byte %01110000
    .byte %01010000
    .byte %01010000
    .byte %01010000
    .byte %01010000
    .byte %01110000
    .byte %00100000
    .byte %00000000
    .byte %00000000

hello_world3
    .byte %00000000
    .byte %00000000
    .byte %01010010
    .byte %01010111
    .byte %01110101
    .byte %01110101
    .byte %01110101
    .byte %01010101
    .byte %01010111
    .byte %01010010
    .byte %01010000
    .byte %01010000

hello_world4
    .byte %00000000
    .byte %00000000
    .byte %01000010
    .byte %01000010
    .byte %01000010
    .byte %01000010
    .byte %01000010
    .byte %01100010
    .byte %01110010
    .byte %01010010
    .byte %00000110
    .byte %00000110

hello_world5
    .byte %00000000
    .byte %00000000
    .byte %00110010
    .byte %01110010
    .byte %01010000
    .byte %01010000
    .byte %01010010
    .byte %01010010
    .byte %01110010
    .byte %00110010
    .byte %00010010
    .byte %00010010

gentext.py

  • Like 3
  • Thanks 2

Share this post


Link to post
Share on other sites
Quote

On that topic, what do the rest of you use as a utility language for data generations/manipulation and the like? I had been using Bash (UNIX shell script) and C, but I forced myself recently to learn some Python, which I have found immensely useful for these kinds of purposes.

Personally, I use Makefiles for what they're good at, but also Perl for simple things — like parsing sources and writing Makefiles based on their inter-dependencies — and Common Lisp for more complex things.

 

Disclaimer: I promise my real code is nowhere near as big a mess as these utilities might lead you to believe.

 

 

 

Convert To Speakjet

 

All the tools used in Grizzards are in the GitHub repo, but the one that others might find useful particularly is the convert-to-speakjet Perl script. It takes a text file in the form:

PhraseLabel:
Say something clever

DifferentUtterance:
Say something different

… and converts it into a series of .byte data for the individual phonemes, based on a dictionary file in the format provided in the SpeakJet developers' kits.

 

The output has labels like Speech_PhraseLabel followed by the SpeakJet bytes (ending with $ff as “usual” for the SpeakJet).

 

The dictionary for Grizzards has a couple of thousand words, and it's relatively simple to expand the dictionary file when you find you were missing something.

 

I work that into the Make process and .include the phrase files to keep from having and “copy and paste” dependencies — the object file depends upon the program source, which in turn depends upon the included (generated) phrase source file, which in turn depends upon the original, editable .txt file. But the source it generates is marginally readable and could be copied-and-pasted into your source tree.

really

If there's interest, I could try to extract that utility into a slightly more stand-alone form, but the script is here and the dictionary file is here. You'd also need to .include the file that maps the SpeakJet constant names to their numerical values, which is here. I think that for dasm you might have to do a “replace all” of := with .equ in that last file?

 

usage: ./convert-to-speakjet InputFileName.txt SpeakJet.dic OutputFileName.s (or .asm if you prefer)

 

 

Skyline Tool

 

The big Lisp utility monolith probably deserves also to be cleaned up, but it can do nice things like read common file formats and convert them into formats that at least I find useful on various “retro” systems. Nominally, it should compile on any modern OS with Steel Bank Common Lisp (sbcl), but I haven't actually tested it except on Linux. (It would be easy to port to another Lisp compiler, but I think I did a handful of implementation-dependent things.)

 

In Grizzards, it converts PNG images into “big” 48×42px graphics and smaller 16×16px and 8×8px graphics from “sprite sheets.” (Those are in the usual inverted order, with each 8px wide vertical strip broken into its own table.) The only graphics not rendered through it in Grizzards are the backgrounds, although I had always meant to go that way and just never got around to it.

 

It also converts the music from MIDI into a set of TIA register values for NTSC and PAL tunings.

 

It somewhat randomly contains a driver for an old serial-port EPROM programmer that I sometimes was using, although now-a-days I have an el cheapo USB one like everyone else. But it is capable of burning EPROMs on a BP EP-1 on Linux, if anyone else still has one of those. They're probably useful as a doorstop or a murder weapon as well, those things are sturdy.

 

A version of it has lately been learning to read TMX and TSX (and linked PNG) files from Tiled, and RLE compress the tile map portion, to try something new and more complicated for my next “retro” (but not 2600) project.

  • Like 1

Share this post


Link to post
Share on other sites

I use Python, which makes accessing image data particualrly easy.

This example is terrible code, but at least it gives some idea of loading an image and accessing pixels in the image.

The example takes a graphics file (BMP/JPG/GIF/PNG... doesn't really matter), and processes it to a text file (in this case, hardwired path/filename) of data statements for assembly and inclusion in your atari game.

 

from PIL import Image
import sys


def process(out, source):

    im = Image.open(source)
    pix = im.load()

    out.write('; created by logo.py\n')
    out.write('; converted from image \'' + source + '\'\n')
    out.write('; size = 6 columns x '+ str(im.size[1]) + ' rows\n')


    out.write('\n')

    out.write('__COPYRIGHT_ROWS = ' + str(im.size[1]) + '\n')

    for x in range(0, im.size[0],8):

        out.write('__IMG' + str(int(x/8)) + '\n')
        for y in range(0, im.size[1]):

            b8 = 0
            for subpix in range(0, 8):
                p = 0
                if pix[x + subpix, y] != 0:
                    p = 1
                b8 = (b8 << 1) | p

            out.write(' .byte ' + str(b8) + '\n')
        out.write('\n')
    out.write('\n')

    out.write('; EOF')
    im.close()


f = open('./copyright.asm', 'w')
process(f, sys.argv[1])
f.close()

Yeah, I know my Python-fu could be improved here, but at least it works :P

 

 

  • Like 1

Share this post


Link to post
Share on other sites

In my assembler code, I've pre-defined all the on/off bit patterns for various bit positions using underscore for 0 and X for 1, so that I can define data like this.... which makes it much more readable to me...  in this example I have a "small" character shape at left (2 bits wide), and a "large" version of the same character at right (4 bits wide).

 

__CHAR_EXAMPLE

    dc _X | _XX_   ;  0
    dc XX | _XX_   ;  1
    dc XX | __X_   ;  2
    dc __ | __X_   ;  3
    dc XX | XX_X   ;  4
    dc __ | ___X   ;  5
    dc X_ | ___X   ;  6
    dc XX | XXXX   ;  7
    dc __ | ___X   ;  8
    dc      ___X   ;  9
    dc      XXXX   ; 10
    dc      ____   ; 11
    dc      ___X   ; 12
    dc      XXXX   ; 13
    dc      ____   ; 14
    dc      __XX   ; 15
    dc      _XX_   ; 16
    dc      ____   ; 17
    dc      ____   ; 18
    dc      ____   ; 19
    dc      ____   ; 20

The defines are...

 

____ = %000000000
___X = %000000001
__X_ = %000000010
__XX = %000000011
_X__ = %000000100
_X_X = %000000101
_XX_ = %000000110
_XXX = %000000111
X___ = %000001000
X__X = %000001001
X_X_ = %000001010
X_XX = %000001011
XX__ = %000001100
XX_X = %000001101
XXX_ = %000001110
XXXX = %000001111


__ = %000000000
_X = %000010000
X_ = %000100000
XX = %000110000

__ = %000000000
_X = %000010000
X_ = %000100000
XX = %000110000

 

More generically, in my C-code I've created defines for all 256 bit patterns. I've struggled to find alternatives for "_" and "X" which look nicer - for example the block-Unicode characters, but these do not seem usable as symbol names. The full set of defines for C code is in the attached file.  Sample C usage...

 

{   // FRAME_SKELETON = 21

    1,0,

    ________,________, BONE, ____,     //00
    ________,________, BONE, BONE,     //01
    ____XXXX,________, BONE, BONE,     //02
    ___XXXXX,X_______, BONE, BONE,     //03
    ___X__X_,_X______, BONE, BONE,     //04
    ___X__X_,_X______, BONE, BONE,     //05
    ___XXXXX,X_______, BONE, BONE,     //06
    ____X_X_,X_______, BONE, BONE,     //07
    _____X_X,________, BONE, BONE,     //08
    ______X_,________, BONE, BONE,     //09
    ___XXXXX,X_______, BONE, BONE,     //10
    __X___X_,_X______, BONE, BONE,     //11
    _XX_XXXX,_XX_____, BONE, BONE,     //12
    _X____X_,__X_____, BONE, BONE,     //13
    ____XXXX,X_______, BONE, BONE,     //14
    _XX__XXX,_XX_____, BONE, BONE,     //15
    X___X_X_,X__X____, BONE, BONE,     //16
    ____X___,X_______, BONE, BONE,     //17
    ___XX___,XX______, BONE, BONE,     //18
    ____X___,X_______, BONE, BONE,     //19
    ________,________, BONE, BONE,     //20
    ___XXX_X,XX______, BONE, BONE,     //21
    ________,________, BONE, BONE,     //22

    -5,0,    // x,y

    ____XX__, BONE,    // 0
    ____XX__, BONE,    // 1
    ________, BONE,    // 2
    ___XXX__, BONE,    // 3
    __X_X_X_, BONE,    // 4
    ___XXX__, BONE,    // 5
    ____X___, BONE,    // 6
    ___X_X__, BONE,    // 7
    ___X_X__, BONE,    // 8

    },

 

bitpatterns.h

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...