123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
- /******************************************************************************
- *
- * project name: TI-68k Developer Utilities
- * file name: tttiler.c
- * initial date: 24/11/2000
- * authors: thomas.nussbaumer@gmx.net
- * description: splits a binary image file (ImageStudio) into tiles
- *
- ******************************************************************************/
- /*
- This file is part of TI-68k Developer Utilities.
- This file is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- As a special exception, UNMODIFIED copies of tttiler may also be
- redistributed or sold without source code, for any purpose. (The Lesser
- General Public License restrictions do apply in other respects; for example,
- they cover modification of the program.) This exception notice must be
- removed on modified copies of this file.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "tt.h" // generic defines
- #include "ttversion.h" // TI-68k Developer Utilities version info
- #include "revtools.h"
- #ifdef FILE_REVISION
- #undef FILE_REVISION
- #endif
- #define FILE_REVISION "1.7"
- //=============================================================================
- // outputs usage information of this tool
- //=============================================================================
- void PrintUsage() {
- fprintf(USAGE_OUT, "Usage: tttiler [-h|-v|-ht|-vt] <infile> <width> <height> <t_width> <t_height> <entries> <outfile> (array_name)\n"\
- " -h ... tile from left to right and up to down\n"\
- " -v ... tile from up to down and left to right\n"\
- " -ht ... like -h, but generates complete test program\n"\
- " -vt ... like -v, but generates complete test program\n"\
- " infile ... binary image file generated with ImageStudio\n"\
- " width ... width of infile in pixel\n"\
- " height ... height of infile in pixel\n"\
- " t_width ... width of one tile in pixel (<=32)\n"\
- " t_height ... height of one tile in pixel\n"\
- " entries ... number of data fields per line (0<entries<=20)\n"\
- " outfile ... output filename (use - as name for output to stdout)\n"\
- " array_name ... optional name of array to generate\n\n"\
- " splits binary image file generated with ImageStudio in single\n"\
- " sprites (tiles) and generates C source code\n"\
- " including the necessary macros to access them.\n\n"\
- "NOTE: only 8, 16 and 32 pixel wide tiles are generated.\n"\
- " If the tilewidth is not exactly one of these widths,\n"\
- " the sprites are filled up to the right with empty pixels\n"\
- "NOTE2: the width of the input file have to be a multiple of 8\n"\
- " otherwise ImageStudio and tttiler will not treat it correctly\n\n");
- }
- #define DIR_HORIZONTAL 0
- #define DIR_VERTICAL 1
- #define MODE_MONO 0
- #define MODE_GRAY4 1
- #define TESTPRG_ON 0
- #define TESTPRG_OFF 1
- //-----------------------------------------------------------------------------
- // globals
- //
- // to reduce the function parameters we are using almost only globals
- // (bad idea in general, but perfect for rapid prototyping)
- //-----------------------------------------------------------------------------
- FILE* outfp;
- int width;
- int height;
- int tilewidth;
- int tileheight;
- int direction;
- int mode;
- int hcount;
- int vcount;
- long insize;
- unsigned char* buffer;
- int dest_width;
- int padding;
- int entries;
- int padding_mask;
- char* arrayname;
- char str_height[255];
- char str_nr[255];
- char str_macro[255];
- //=============================================================================
- // converts given string into uppercase
- //=============================================================================
- void ToUppercase(char* str) {
- while (*str) {
- *str = (char)toupper(*str);
- str++;
- }
- }
- //=============================================================================
- // extract a single tile
- //=============================================================================
- void WriteTile(long offset,int x,int y) {
- int h;
- int bytes_per_line = width/8;
- unsigned char* addr = buffer + offset + y*bytes_per_line + x/8;
- unsigned int data1 = 0;
- //unsigned int data2 = 0;
- unsigned int shift = x % 8;
- for (h=0;h<tileheight;h++) {
- switch(dest_width) {
- case 8:
- data1 = (*addr & 0xff) << 8;
- data1 |= (*(addr+1) & 0xff);
- data1 = (data1 >> (8-shift)) & padding_mask;
- fprintf(outfp,"0x%02x",data1);
- break;
- case 16:
- data1 = (*addr & 0xff) << 16;
- data1 |= (*(addr+1) & 0xff) << 8;
- data1 |= (*(addr+2) & 0xff);
- data1 = (data1 >> (8-shift)) & padding_mask;
- fprintf(outfp,"0x%04x",data1);
- break;
- default:
- data1 = (*addr & 0xff) << 24;
- data1 |= (*(addr+1) & 0xff) << 16;
- data1 |= (*(addr+2) & 0xff) << 8;
- data1 |= (*(addr+3) & 0xff);
- if (shift) {
- data1 = (data1 << shift) & padding_mask;
- data1 |= (*(addr+4) & 0xff) >> (8-shift);
- }
- data1 &= padding_mask;
- fprintf(outfp,"0x%08x",data1);
- break;
- }
- if (h == tileheight-1) {}//fprintf(outfp,"");
- else if (!((h+1) % entries)) fprintf(outfp,",\n");
- else fprintf(outfp,",");
- addr += bytes_per_line;
- }
- }
- //=============================================================================
- // process a complete plane starting at given offset
- //=============================================================================
- void ProcessPlane(long offset) {
- int x;
- int y;
- if (direction == DIR_HORIZONTAL) {
- for (y=0;y<vcount;y++) {
- for (x=0;x<hcount;x++) {
- fprintf(outfp,"// tile %d\n",y*hcount+x);
- WriteTile(offset,x*tilewidth,y*tileheight);
- if ((x == hcount - 1) && (y == vcount - 1)) {
- fprintf(outfp,"\n");
- }
- else {
- fprintf(outfp,",\n");
- }
- }
- }
- }
- else {
- for (x=0;x<hcount;x++) {
- for (y=0;y<vcount;y++) {
- fprintf(outfp,"// tile %d\n",x*vcount+y);
- WriteTile(offset,x*tilewidth,y*tileheight);
- if ((x == hcount - 1) && (y == vcount - 1)) {
- fprintf(outfp,"\n");
- }
- else {
- fprintf(outfp,",\n");
- }
- }
- }
- }
- }
- //=============================================================================
- // write test program - part 1
- //=============================================================================
- void WriteTestProgram1() {
- fprintf(outfp,"#define SAVE_SCREEN\n");
- fprintf(outfp,"#include <tigcclib.h>\n");
- fprintf(outfp,"short _ti89,_ti92plus;\n\n\n");
- }
- //=============================================================================
- // write test program - part 2
- //=============================================================================
- void WriteTestProgram2() {
- fprintf(outfp,"\n\nvoid _main(void) {\n");
- fprintf(outfp," short x,y;\n");
- fprintf(outfp," short tilewidth = %d;\n",tilewidth);
- fprintf(outfp," short vcount = %d;\n",vcount);
- fprintf(outfp," short hcount = %d;\n",hcount);
- if (mode == MODE_GRAY4) {
- fprintf(outfp," short i;\n");
- fprintf(outfp," if (!GrayOn()) return;\n");
- fprintf(outfp," memset(GetPlane(0),0,LCD_SIZE);\n");
- fprintf(outfp," memset(GetPlane(1),0,LCD_SIZE);\n");
- }
- else {
- fprintf(outfp," memset(LCD_MEM,0,LCD_SIZE);\n");
- }
- if (direction == DIR_HORIZONTAL) {
- fprintf(outfp," for (y=0;y<vcount;y++) {\n");
- fprintf(outfp," for (x=0;x<hcount;x++) { \n");
- fprintf(outfp," short nr = y*hcount+x;\n");
- }
- else {
- fprintf(outfp," for (x=0;x<hcount;y++) {\n");
- fprintf(outfp," for (y=0;y<vcount;y++) { \n");
- fprintf(outfp," short nr = x*vcount+y);\n");
- }
- if (mode == MODE_GRAY4) {
- fprintf(outfp," for (i=0;i<2;i++) {\n");
- fprintf(outfp," Sprite%d(x*tilewidth,y*%s,%s,%s(i,nr),GetPlane(i),SPRT_OR);\n",dest_width,str_height,str_height,str_macro);
- fprintf(outfp," }\n");
- }
- else {
- fprintf(outfp," Sprite%d(x*tilewidth,y*%s,%s,%s(nr),LCD_MEM,SPRT_OR);\n",dest_width,str_height,str_height,str_macro);
- }
- fprintf(outfp," }\n");
- fprintf(outfp," }\n");
- fprintf(outfp," ngetchx();\n");
- if (mode == MODE_GRAY4) fprintf(outfp," GrayOff();\n");
- fprintf(outfp,"}\n\n");
- }
- //=============================================================================
- // nomen omen est
- //=============================================================================
- int main(int argc, char* argv[]) {
- FILE* infp;
- int i;
- int testprg;
- // write it only when not in "output to stdout" mode !!!
- if (!(argc >= 9 && !strcmp(argv[8],"-"))) {
- PRINT_ID("TTTiler");
- }
- if (argc == 1) {
- PrintUsage();
- return 1;
- }
- if (argc != 9 && argc != 10) {
- fprintf(stderr,"ERROR: invalid number of parameters\n");
- PrintUsage();
- return 1;
- }
- //-------------------------------------------------------------------------
- // parse direction flag
- //-------------------------------------------------------------------------
- if (!strcmp(argv[1], "-h")) direction = DIR_HORIZONTAL, testprg = TESTPRG_OFF;
- else if (!strcmp(argv[1], "-v")) direction = DIR_VERTICAL, testprg = TESTPRG_OFF;
- else if (!strcmp(argv[1], "-ht")) direction = DIR_HORIZONTAL, testprg = TESTPRG_ON;
- else if (!strcmp(argv[1], "-vt")) direction = DIR_VERTICAL, testprg = TESTPRG_ON;
- else {
- fprintf(stderr,"ERROR: neither -h nor -v and neither -ht nor -vt specified\n");
- PrintUsage();
- return 1;
- }
- //-------------------------------------------------------------------------
- // parse width/height/tilewidth/tileheight/entries
- //-------------------------------------------------------------------------
- if (sscanf(argv[3],"%d",&width) != 1) {
- fprintf(stderr,"ERROR: cannot parse width=%s\n",argv[3]);
- PrintUsage();
- return 1;
- }
- if (width % 8) {
- fprintf(stderr,"ERROR: width not multiple of 8 (width=%d)\n",width);
- PrintUsage();
- return 1;
- }
- if (width <= 0) {
- fprintf(stderr,"ERROR: negative or zero width not allowed (width=%d)\n",width);
- PrintUsage();
- return 1;
- }
- if (sscanf(argv[4],"%d",&height) != 1) {
- fprintf(stderr,"ERROR: cannot parse height=%s\n",argv[4]);
- PrintUsage();
- return 1;
- }
- if (height <= 0) {
- fprintf(stderr,"ERROR: negative or zero height not allowed (height=%d)\n",height);
- PrintUsage();
- return 1;
- }
- if (sscanf(argv[5],"%d",&tilewidth) != 1) {
- fprintf(stderr,"ERROR: cannot parse tilewidth=%s\n",argv[5]);
- PrintUsage();
- return 1;
- }
- if (tilewidth <= 0) {
- fprintf(stderr,"ERROR: negative or zero tilewidth not allowed (tilewidth=%d)\n",tilewidth);
- PrintUsage();
- return 1;
- }
- if (tilewidth > 32) {
- fprintf(stderr,"ERROR: tilewidth larger than 32 not allowed (tilewidth=%d)\n",tilewidth);
- PrintUsage();
- return 1;
- }
- if (tilewidth <= 8) dest_width = 8;
- else if (tilewidth <= 16) dest_width = 16;
- else dest_width = 32;
- padding = dest_width - tilewidth;
- padding_mask = 0;
- for (i=0;i<padding;i++) padding_mask |= 1 << i;
- padding_mask = ~padding_mask;
- if (tilewidth <= 8) padding_mask &= 0xff;
- else if (tilewidth <= 16) padding_mask &= 0xffff;
- if (tilewidth > width) {
- fprintf(stderr,"ERROR: tilewidth larger than width\n");
- PrintUsage();
- return 1;
- }
- if (sscanf(argv[6],"%d",&tileheight) != 1) {
- fprintf(stderr,"ERROR: cannot parse tileheight=%s\n",argv[6]);
- PrintUsage();
- return 1;
- }
- if (tileheight <= 0) {
- fprintf(stderr,"ERROR: negative or zero tileheight not allowed (tileheight=%d)\n",tileheight);
- PrintUsage();
- return 1;
- }
- if (tileheight > height) {
- fprintf(stderr,"ERROR: tileheight larger than height\n");
- PrintUsage();
- return 1;
- }
- if (sscanf(argv[7],"%d",&entries) != 1) {
- fprintf(stderr,"ERROR: cannot parse entries=%s\n",argv[7]);
- PrintUsage();
- return 1;
- }
- if (entries <= 0 || entries > 20) {
- fprintf(stderr,"ERROR: invalid value for entries (entries=%d)\n",entries);
- PrintUsage();
- return 1;
- }
- hcount = width / tilewidth;
- vcount = height / tileheight;
- //-------------------------------------------------------------------------
- // open inputfile
- //-------------------------------------------------------------------------
- if (!(infp = fopen(argv[2],"rb"))) {
- fprintf(stderr,"ERROR: cannot open inputfile %s\n",argv[2]);
- PrintUsage();
- return 1;
- }
- //-------------------------------------------------------------------------
- // get and check input size
- //-------------------------------------------------------------------------
- if (fseek(infp,0,SEEK_END)) {
- fprintf(stderr,"ERROR: cannot find end of inputfile %s\n",argv[2]);
- PrintUsage();
- fclose(infp);
- return 1;
- }
- insize = ftell(infp);
- if (insize == -1L) {
- fprintf(stderr,"ERROR: cannot evaluate size of inputfile %s\n",argv[2]);
- PrintUsage();
- fclose(infp);
- return 1;
- }
- rewind(infp);
- if (insize == (long)height*(long)width/8) {
- mode = MODE_MONO;
- }
- else if (insize == (long)height*(long)width/4) {
- mode = MODE_GRAY4;
- }
- else {
- fprintf(stderr,"ERROR: filesize (%ld) doesn't correspond with height/width\n",insize);
- PrintUsage();
- fclose(infp);
- return 1;
- }
- //-------------------------------------------------------------------------
- // allocate buffer, read in all bytes and close input file
- //-------------------------------------------------------------------------
- if (!(buffer = malloc(insize))) {
- fprintf(stderr,"ERROR: cannot allocate %ld bytes for input data\n",insize);
- PrintUsage();
- fclose(infp);
- return 1;
- }
- if (fread(buffer,insize,1,infp) != 1) {
- fprintf(stderr,"ERROR: cannot read %ld bytes from inputfile %s\n",insize,argv[2]);
- PrintUsage();
- fclose(infp);
- free(buffer);
- return 1;
- }
- fclose(infp);
- //-------------------------------------------------------------------------
- // open outputfile
- //-------------------------------------------------------------------------
- if (!strcmp(argv[8],"-")) {
- outfp = stdout;
- }
- else if (!(outfp = fopen(argv[8],"w"))) {
- fprintf(stderr,"ERROR: cannot open outputfile %s\n",argv[8]);
- PrintUsage();
- free(buffer);
- return 1;
- }
- if (argc == 10) arrayname = argv[9];
- else arrayname = "data";
- if (outfp != stdout) {
- printf("infile = %s\n",argv[2]);
- printf("filesize = %ld\n",insize);
- printf("direction = %s\n",((direction==DIR_HORIZONTAL) ? "HORIZONTAL":"VERTICAL"));
- printf("mode = %s\n",((mode==MODE_MONO) ? "MONO":"GRAY4"));
- printf("width = %d\n",width);
- printf("height = %d\n",height);
- printf("tilewidth = %d\n",tilewidth);
- printf("tileheight = %d\n",tileheight);
- printf("hcount = %d\n",hcount);
- printf("vcount = %d\n",vcount);
- printf("tilecount = %d\n",hcount * vcount);
- printf("destwidth = %d\n",dest_width);
- printf("padding = %d\n",padding);
- printf("paddmask = 0x%08x\n",padding_mask);
- printf("outfile = %s\n",argv[8]);
- printf("arrayname = %s\n",arrayname);
- }
- sprintf(str_nr,"TILENUMBER_%s",arrayname);
- ToUppercase(str_nr);
- sprintf(str_height,"TILEHEIGHT_%s",arrayname);
- ToUppercase(str_height);
- sprintf(str_macro,"TILEADDR_%s",arrayname);
- ToUppercase(str_macro);
- if (testprg == TESTPRG_ON) WriteTestProgram1();
- //-------------------------------------------------------------------------
- // write header
- //-------------------------------------------------------------------------
- fprintf(outfp,"// number of tiles in array %s\n",arrayname);
- fprintf(outfp,"#define %s %d\n\n",str_nr,hcount*vcount);
- fprintf(outfp,"// height of one tile in array %s\n",arrayname);
- fprintf(outfp,"#define %s %d\n\n",str_height,tileheight);
- if (mode == MODE_GRAY4) {
- fprintf(outfp,"// macro returns the address of tile nr of plane p from array %s\n",arrayname);
- fprintf(outfp,"#define %s(p,nr) &(%s[p][%s*nr])\n\n",str_macro,arrayname,str_height);
- }
- else {
- fprintf(outfp,"// macro returns the address of tile nr from array %s\n",arrayname);
- fprintf(outfp,"#define %s(nr) &(%s[%s*nr])\n\n",str_macro,arrayname,str_height);
- }
- switch(dest_width) {
- case 8: fprintf(outfp,"unsigned char %s",arrayname); break;
- case 16: fprintf(outfp,"unsigned short %s",arrayname); break;
- default: fprintf(outfp,"unsigned long %s",arrayname); break;
- }
- if (mode == MODE_GRAY4) fprintf(outfp,"[2][%s*%s] = {{\n",str_nr,str_height);
- else fprintf(outfp,"[%s*%s] = {\n",str_nr,str_height);
- ProcessPlane(0);
- if (mode == MODE_GRAY4) {
- fprintf(outfp,"},\n// ---- plane 2 ----\n{\n"/*,hcount*vcount*tileheight*/);
- ProcessPlane(insize/2);
- fprintf(outfp,"}");
- }
- fprintf(outfp,"};\n");
- if (testprg == TESTPRG_ON) WriteTestProgram2();
- if (outfp != stdout) fclose(outfp);
- free(buffer);
- return 0;
- }
- //#############################################################################
- //###################### NO MORE FAKES BEYOND THIS LINE #######################
- //#############################################################################
- //
- //=============================================================================
- // Revision History
- //=============================================================================
- //
- // Revision 1.7 2009/01/25 Lionel Debroux
- // Changes by Romain Liévin and/or me for 64-bit compatibility.
- // Adapt to new version display (revtools.h).
- //
- // Revision 1.6 2002/02/07 09:49:38 tnussb
- // all local includes changed, because header files are now located in pctools folder
- //
- // Revision 1.5 2001/06/20 13:05:41 Thomas Nussbaumer
- // (1) tilenumber output corrected
- // (2) suppressing following comma after the last tile of a plane
- // (3) writing now macros to access the tiles
- // (4) handling of output redirection to stdout (outfilename == "-")
- // (5) customizable arrayname (commandline parameter)
- // (6) test program output adapted to TIGCC 0.90 (int -> short)
- //
- // Revision 1.4 2000/11/28 00:08:29 Thomas Nussbaumer
- // using now USAGE_OUT stream for usage info
- //
- // Revision 1.3 2000/11/27 23:25:46 Thomas Nussbaumer
- // bug fix: generating now correct test program for monochrome tiles, too
- //
- // Revision 1.2 2000/11/26 21:35:02 Thomas Nussbaumer
- // (1) some debug outputs removed
- // (2) 16 pixel-wide sprites mode fixed
- //
- // Revision 1.1 2000/11/26 20:01:02 Thomas Nussbaumer
- // initial version
- //
- //
- //
|