Q L H A C K E R ' S J O U R N A L =========================================== Supporting All QL Programmers =========================================== #19 November 1994 The QL Hacker's Journal (QHJ) is published by Tim Swenson as a service to the QL Community. The QHJ is freely distributable. Past issues are available on disk, via e-mail, or via the Anon-FTP server, garbo.uwasa.fi. The QHJ is always on the look out for article submissions. QL Hacker's Journal c/o Tim Swenson 5615 Botkins Rd Huber Heights, OH 45424 USA (513) 233-2178 swensotc@ss2.sews.wpafb.af.mil swensotc@p2.ams.wpafb.af.mil tswenson@dgis.dtic.dla.mil .bd .ul EDITOR'S FORUMN .bo .uo Well, it looks like another issues has taken longer that I would like. It's been one of those "too busy to program" type of dry spells. The only key item of news is that as I am writing this the latest version of C68 v 4.2 has partialy come out. I received the zipped version of C68 Runtimes disk #1. Dave Walker should be sending the rest of the disk out soon. Since I have Internet access I am on Dave's mailing list for updates of C68. Dave prefers to distribute the package as a number of large mail messages. When I get them, I convert them back into a binary file and get them over to the QL. I then send a copy of the disks to Don Walterman of QBOX-USA and to Bob Dyl of the IQLR. If I remember, I can upload them to a number of QL FTP servers on the net. The key ones are maya.dei.unipd.it and ftp.nvg.unit.no. For those interested I have a new Sinclair Internet Resources List that has a number of Sinclair World Wide Web sites listed. The amazing thing is that there is a ZX81 home page out there. If you would like a copy of the list, send me a note. I tried posting it to comp.sys.sinclair, but I don't know if I was successfull. The last item of note is that I have finally broken down and bought some new hardware. I went out and picked up a new HP Deskjet 520 inkjet printer. It's output is almost laser quality, esp. with the specially designed inkjet paper. This is not something I normally do. My last printer, a DWP-230 daisy wheel, cost a grand total of $1 at a garage sale. And it has worked for 2 years with out failure. It was only when I thought it died that I considered buying the Deskjet. (I forgot that these diable HI-TYPE II printers do run out of ribbon and will not print after that. And I thought it was dead.) That's all I have for now. Happy Hacking. .bd .ul DISPLAYING TI GRAPHICS FILES .bo .uo [ Jeff Kuhlman has written an interesting program to display a TI-Artist instance file on the QL. I don't know how many have been wanting to do this, but here it is. On the disk that Jeff sent me, were many example files. If you are interested in this, I can provide a disk with all of the sample files. - ED ] /* SHOWTIA_C - a c68 file for the QL to display */ /* TI-ARTIST instances. This is NOT the proper way */ /* to program in that I write directly to the screen */ /* This is because: a) it's a LOT faster and */ /* b) I couldn't figure out how to */ /* scale the window properly */ /* December 10, 1993 Ver 1.0 Jeffrey A. Kuhlmann */ #include "qlib.h" /* because I use QDOS calls */ #include "stdio.h" /* because I open files */ #include "string.h" /* because I use string functions */ #include "stdlib.h" /* because I use atoi() function */ char infn[81]; /* input file name */ char str1[81]; /* input string from file */ FILE *inf,*outf; /* files to open */ int arry[20]; /* utility array */ char rows[81]; /* row string */ char cols[81]; /* columns string */ int ctr,end,delim,col,row; int rctr,cctr,cptr; int chardat[8],chrptr; long qres; char *scrn; /* pointer to absolute screen memory */ char *_endmsg=NULL; /* omit end message */ main(argc,argv) int argc; char *argv[]; { if(argc<2) { puts("TI-ARTIST VIEWER FOR QDOS"); puts("Press any key when done"); puts("viewing picture..."); puts("TI-Artist file name? (w/o _I)"); gets(infn); /* get filename from user */ } else strcpy(infn,argv[1]); strcat(infn,"_I"); /* add necessary _i to name */ inf=fopen(infn,"r"); /* try to open file */ /* this function forces 4 color, monitor mode */ mt_dmode("4","0"); /* open whole screen for access */ outf=fopen("con_512x256a0x0_32","w"); qres=fgetchid(outf); if (!inf) {printf("Can't open %s",infn); exit(7);} /* error opening file */ sd_clear(qres,-1); /* clear screen */ /* for(ctr=0;ctr<16;ctr++)puts(""); */ /* needed only when end message */ /* enabled */ fgets(str1,81,inf);/* read # of rows, cols needed */ rowcol(); for(rctr=0;rctr int x[1000]; /* global array for storage of resultant number */ int topdig; main() { int c; pow2(100); bnprint(); while ( ( c = getchar() ) == "" ) ; /* pause screen */ } pow2 ( n ) int n; { bnset1( 1 + n/3); while ( n -- > 0 ) bnmult(2); } bnset1(maxdig) int maxdig; { int i; topdig = maxdig; for ( i = 0; i < topdig; i++) x[i] = 0; x[0] = 1; } bnmult( a ) int a; int i, carry; carry = 0; for ( i = 0; i < topdig; i++ ) { x[i] = a * x[i] + carry; carry = 0; if ( x[i] >= 10 ) { x[i] -= 10; carry = 1; } } if (carry) x[topdig++] = carry; } bnprint () { int i; for ( i = topdig-1; i >= 0; i--) printf("%d", x[i]); printf("\n"); } .bd .ul DYNAMIC WINDOWS - ANOTHER APPROACH .bo .uo In a back issue of the QHJ I wrote a SuperBasic program that saves a section of the screen to memory and brings it back again. This allows you to save a section of the screen where you are about the put a new window, draw to window, and then bring back what was under the window when you are done with the window. Jonathan Vanderwall brings another approach to this problem. He is interested in using drop-down menus (which are just specialty windows). He first saves the entire screen to ramdisk, draws the pull-down menus, and when done, uses LBYTES to reload the screen. He says that he gets pretty good responses for this routines. This is sort of a brute force approach to the problem, but it does reach a solution. I thought this approach was unelegant and a bit of a kludge, but if I found problems writing the routines I wanted, then I would use this as a backup. When developing sometimes you take the path of least resistance, even if it's not the cleanest path. .bd .ul SOUNDEX .bo .uo Soundex is an algorithm for storing words, primarily names, in a number format so that they could be easily look up, and words that sound alike will have almost the same soundex result. This is sort of the thing they use when you call information and ask for a persons number. They will type it up, and it will return all persons that sound similar to the name you gave (just in case you don't know the exact spelling). This program comes out of the Sept 1994 issue of the C/C++ Users Journal. I've run this program through C68, but it does not like the continue and break statements in the for loop. I've looked in the first edition of K&R and it supports this contruct, so I'm puzzled as to why C68 does not support the construct. I am presenting the program here for the following reasons: 1] It's an interesting simple algorithm to tinker with. 2] It's a simple enough program that it would be reworked into almost any language. 3] Because it should compile in C68 as defined by K&R. I'm hoping that either the answer to why it won't compile is easy or that it will bring a discussion on possible weaknesses in C68. /* soundex.c Jeff Rossen */ #include #include #define MODIFIED_VERSION /* remove for original */ #define MAX_LENGTH 20 /* max 3 of char to check */ #define SOUNDEX_LENGTH 4 /* length of Soundex code */ #define ALPHA_OFFSET 65 int main(int argc, char *argv[]) { char code[SOUNDEX_LENGTH+1]; soundex(argv[1], code); printf("The code is %s \n",code); return(0); } int soundex(char *in_name, char *code) { /* ctable contains the Soundex value for each letter in alphabetical order. 0 represents letters which are to be ignored. */ static char ctable[] = {"01230120022455012623010202"}; /* abcdefghijklmnopqrstuvwxyz */ char name[MAX_LENGTH+1]; char prior = ' ', c; short i, y=0; /* convert all to uppercase */ for(i=0; in_name[i] && i < MAX_LENGTH; i++) name[i] = toupper(in_name[i]); name[i]='\0'; /* generate 1st character of Soundex code */ code[0] = name[0]; y=1; code[y]='\0'; #ifdef MODIFIED_VERSION if (name[0] == 'K') /* modification */ code[0]= 'C'; else if (name[0] == 'P' && name[1] == 'H') code[0]='F'; #endif /* loop through rest of name until code complete *. for(i=1; name[i]; i++) { if (! isalpha(name[i])) /* skip non-alpha */ continue; /* skip successive occurance */ if (name[i] == prior) continue; prior = name[i]; /* lookup letter in table */ c = name[i] - ALPHA-OFFSET; if (ctable[c] == 0) /* ignore this letter */ continue; code[y++] = ctable[c]; /* add to code */ code[y] = '\0'; if (strlen(code) >= SOUNDEX_LENGTH) break; /* code is complete */ } while (strnlen(code) < SOUNDEX_LENGTH) { code[y++] = '0'; /* pad code with zeros */ code[y] = '\0'; } return(0); }