Subject: [stella] Re: Banker (Utility) v0.01 From: "Andrew Davie" <adavie@xxxxxxxxxxx> Date: Mon, 13 Jan 2003 01:16:39 +1100 |
Whoops! I did it again. Many apologies for my last HTML post. Attached is a ZIP file with a Utility I have recently written, and some sample output from that utility. With a bit of tweaking (addition of command-line switches) it might be of assistance to others. 'Banker', as I call it, is designed to take multiple frames of graphics as input, and split those frames into matrices of sprites (16 bytes deep) over as few 2K banks as possible, satisfying the following criteria.... a) For any frame, ALL of its sprites must be in a single bank b) The matrix definition for the frame must be in the same bank as the sprites it uses c) Sprites definitions may be re-used by multiple frames, if the sprites are identical d) Sprites are defined bottom-up (ie: in reverse byte-sequence, to assist quick drawing). e) Frames themselves are unique, so their matrices are not optimised away, even if frames are identical. The utility outputs one .asm file per bank it needs to create, and a single file containing a table of pointers to the frames. The table gives the bank and frame address for each frame. The ZIP file contains the utility (BANKER.EXE) some sample output (.ASM files) and the graphics files used as input for the sample data (the PNG files). The sample art files (random stuff, really) have been sized to 48 x 80 pixels (the size of my sprite system, for now). The utility is written so that it doesn't care what size the input graphics are - it will cope with undersize or oversize files OK. The utility is used for compiling all of these individual frame files into banks through the following call... banker *.png Note the use of wildcards for filename specification. Alternatively, filenames can be explicitely defined; eg: banker a.png b.png c.png d.png Some command-line switches are also available -v Toggle verbose reporting ON/OFF ... barely functional -Xn Set the frame matrix width to n sprites -Yn Set the frame matrix height to n sprites -Nname Set the output filename prefix to "name" (default = "BANK") Files are processed in left-to-right order, as they are found on the command line. So in the above example, a.png would be packed to frame #0, b.png would be frame #1, etc. When running, the utility displays basic information about the file it is processing, and the size of the image in pixels. After all files have been processed, a summary of the number of frames, number of banks, and details of the usage in each bank is output. Bank files are written to the current working directory in the form... BANK00.ASM First bank BANK01.ASM Second bank ...etc and a single file BANK_FRAMETABLE.ASM The BANK_FRAMETABLE.ASM file holds a table (called 'FrameTable') giving the bank, and an address within the bank, for each of the frames processed from the frame list on the command line. Bank numbers are referred to indirectly through equates, which must be set up in the program including these .ASM files. The file also contains an equate, FRAMECOUNT, which gives the total number of frames in the table. This equate may be used as a bounds-check to guarantee that no attempt is made to display illegal frames. Sample... ------------------------------------------------------------ ; BANK_FRAMETABLE.asm ; Created by Banker v0.01 FrameTable ; Bank <Frame Address >Frame Address # .byte FRAMEBANK00, < FRAME_a_png_0, > FRAME_a_png_0 ; 0 .byte FRAMEBANK00, < FRAME_a_png_1, > FRAME_a_png_1 ; 1 FRAMECOUNT = 2 ; END ------------------------------------------------------------ The table consists of a line per frame. Each line contains a bank number - referenced by an equate value - giving the bank in which the frame itself is defined. A frame definition consists of a colour, and a matrix giving the sprite numbers used to build the frame itself. The sprite data itself comes from the sprite set which starts at the beginning of each bank. Thus, the matrix is a list of sprite indexes. The draw system uses the index to calculate an absolute address of the sprite data for draw purposes. Since sprites are (currently hardwired) at 16-pixels deep, this is a simple calculation. The equate removes any dependancy between the FrameTable and actual physical bank numbering. The programmer needs a list assigning bank equates to actual physical bank numbers - eg: FRAMEBANK00 = 0 FRAMEBANK01 = 1 ...etc In the above case, this would indicate to the draw system that frame 0 is in hardware bank #0, and frame #1 is in hardware bank #1, etc. The individual bank files (BANK00.ASM etc) contain the sprite set - a list of sprites (each 16-bytes, defined bottom-up) used to build a matrix of sprites for the sprite system - and definitions of the frames which are defined in this bank. Each of the frames is referenced (found) by looking up the bank/address in the FrameTable, then switching bank and accessing the frame matrix and spriteset as required. ------------------------------------------------------------ ; BANK01.asm ; Created by Banker v0.01 ; Sprite set. Each line is a single sprite, 16 bytes deep, defined bottom-up ; This bank contains 2 frames, consisting of 39 sprites. .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .byte 17, 19, 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .byte 15, 30, 189, 253, 251, 119, 87, 23, 7, 6, 0, 0, 0, 0, 0, 0 .byte 64, 224, 240, 240, 232, 208, 240, 224, 192, 0, 0, 0, 0, 0, 0, 0 .byte 32, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 6, 8, 8 .byte 0, 1, 4, 8, 20, 136, 8, 12, 72, 136, 144, 16, 32, 0, 64, 1 .byte 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .byte 224, 192, 128, 64, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .byte 232, 232, 192, 161, 129, 65, 129, 67, 3, 1, 1, 1, 0, 0, 0, 0 .byte 255, 255, 253, 245, 244, 200, 208, 162, 160, 160, 200, 160, 192, 208, 64, 80 .byte 213, 82, 36, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .byte 1, 129, 67, 2, 12, 14, 8, 12, 8, 16, 24, 16, 48, 32, 96, 64 .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 63, 125, 122, 224 .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 207, 143, 141, 245 .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 255, 241, 97, 113 .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 255, 227, 195, 227 .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 254, 255, 235, 130 .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 .byte 3, 7, 30, 56, 56, 112, 240, 208, 200, 204, 255, 127, 0, 0, 0, 0 .byte 208, 163, 66, 4, 0, 0, 1, 7, 63, 252, 224, 0, 0, 0, 0, 0 .byte 134, 14, 28, 56, 48, 224, 192, 128, 0, 0, 0, 0, 0, 0, 0, 0 .byte 14, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .byte 23, 127, 247, 166, 3, 7, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0 .byte 14, 30, 250, 238, 182, 110, 182, 222, 252, 248, 0, 0, 0, 0, 0, 0 .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 7, 14, 28, 121, 241 .byte 3, 3, 7, 14, 12, 28, 113, 116, 209, 145, 161, 34, 160, 132, 69, 139 .byte 63, 31, 30, 14, 174, 102, 46, 111, 82, 115, 98, 58, 110, 240, 248, 156 .byte 6, 4, 4, 199, 33, 2, 30, 244, 22, 21, 151, 200, 166, 66, 71, 71 .byte 3, 19, 51, 161, 243, 67, 70, 206, 188, 152, 88, 28, 12, 238, 174, 46 .byte 0, 0, 0, 0, 0, 1, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3 .byte 199, 231, 199, 198, 254, 230, 230, 230, 102, 118, 54, 55, 55, 55, 55, 63 .byte 128, 128, 192, 128, 192, 128, 192, 192, 195, 199, 198, 245, 252, 156, 132, 100 .byte 0, 0, 0, 0, 0, 0, 0, 0, 192, 224, 248, 92, 172, 38, 38, 6 .byte 3, 3, 3, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 .byte 34, 34, 34, 131, 34, 162, 194, 194, 147, 227, 227, 193, 195, 193, 211, 211 .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128 .byte 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 3, 3, 6, 2, 6, 3 .byte 15, 127, 248, 201, 131, 143, 158, 156, 152, 186, 252, 158, 6, 14, 46, 38 .byte 128, 192, 192, 192, 192, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 FRAME_ff0_png_11 .byte $00 ; colour .byte 18, 19, 20, 21, 22, 23 .byte 0, 24, 25, 26, 27, 28 .byte 0, 0, 29, 30, 31, 32 .byte 0, 0, 33, 34, 35, 0 .byte 0, 0, 36, 37, 38, 0 FRAME_eye2_png_12 .byte $00 ; colour .byte 0, 0, 0, 0, 0, 0 .byte 0, 0, 1, 2, 3, 0 .byte 0, 0, 4, 5, 6, 0 .byte 7, 8, 9, 10, 11, 6 .byte 12, 13, 14, 15, 16, 17 ; Total memory = 686 bytes (1362 still free) ------------------------------------------------------------ The (generated) comments at the start of the bank file indicate how many frames and sprites are packed into the bank. The sprite set appears first - currently a list of 16-byte sprites in bottom-up ordering. Then come the frames which reference the sprite set via index. Consider the label FRAME_eye2_png_12 from the above bank definition. The label contains the encoded filename of the original file used to generate the graphics. In this case, the frame came from "eye2.png". The absolute frame number (in terms of the FrameTable table) is also encoded at the end of the label. The current frame format consists of colour 1 byte - colour of the frame matrix A 30-byte matrix giving indexes of sprites. Each sprite comes from the frame set at the top of the file. The comment at the bottom of the file tells how many bytes in the bank have been used, and how many are still free. The utility tries to optimise things by first checking all banks in use to see when it adds a new frame which bank would require the fewest new sprites (and would still be large enough to contain the sprites and frame matrix). So if parts of 'large sprites' re-use small sections which are aligned on the 16-deep grid... then the utility will catch this. Now, that's all very specific to my code - how can this be of use to you RIGHT NOW? Well, it reads graphics files of several formats - specifically JPG, BMP and PNG files - and creates tables of '2600-compatible sprites. If, for example, you wanted to convert some graphics into sprites... you could just run the graphic file through this utility to produce a bank, as above, and then get the converted data from the sprite set. At the moment it's in a 16-byte bottom-up format... but I'm VERY open to adding switches to the command-line to enable this to become the be-all and end-all of sprite conversion utilities. Even now, it might save people some time converting graphics to ASM format... no more manual binary graphics drawing, hopefully. Some possible additions.... o Top-down or bottom-up definitions o Specifying different sprite sizes (ie: not just 16 pixels deep) o Changing the matrix output format (no colour, etc) (plans are at a later stage to add additional data such as collision boxes, etc). o specifying different bank sizes (currently 2K) Well, that's about all I have time for. I'd appreciate any comments/testing/suggestions on this one. Cheers A
Attachment:
banker.zip
Description: Zip compressed data
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [stella] Collaboration, Glenn Saunders | Thread | Re: [stella] 10-in-1 Toymax, Andrew Davie |
Re: [stella] Chip Select Line, Kroko | Date | Re: [stella] 10-in-1 Toymax, Andrew Davie |
Month |