______________________________________________________________________________ The Basix Fanzine Issue 10 - April 1998 editor: Alex Warren email: basix@dewarr.globalnet.co.uk www: http://come.to/axe/basix ______________________________________________________________________________ Hello, good evening and welcome to issue 10, and a (very late) happy new year to you all. Sorry for the lateness of this issue, I've been busy with school work and also contributions have been a bit thin on the ground and I thought it better to wait until I had enough rather than release the tiniest fanzine ever. In a vain attempt to add more information, I've taken a few newsgroup articles which may be of interest and have stuck them in as well. Enjoy... -CONTENTS--------------------------------------------------------------------- Levels are represented by B, I or A for Beginner, Intermediate and Advanced respectively, or a combination. They aren't clear-cut definitions though, so you might find something useful labelled (B) even though you've been programming for 10 years, for example. Unless otherwise stated, the articles apply to all major breeds of BASIC. NEWS: - POWERBASIC 3.5 - BASIX ARTICLE READER ARTICLES: - TIMING by Jakob Krarup (B) - CUSTOMIZED FONTS by Jakob Krarup (I/A) - FRACTAL DIMENSIONS by Razvan Caracas (A) - GRAPHICS IN QBASIC TUTORIAL (PART 1) by "Hacker" aka Damian Nikodem (I) - MAKING LIBRARIES by Alan Copeland (not QBasic) (ALL) PROGRAMS: - 4DD.BAS by "Anna" - NEWTIMER.BAS by "Hacker" aka Damian Nikodem FROM THE NEWSGROUPS: - FOR THOSE OF YOU INTERESTED IN BASIC COMPILERS from John D. Morrison - READING TWO KEYS from CadWright - DETERMINE HOME DIRECTORY from Christy Gemmell - fINPUT FOR QB from Don Schullian LETTERS: - FANZINE TEXT FORMAT, from Bart Veerman INTERNET RESOURCES: - Getting the Fanzine - Websites - Mailing List - Useful BASIC Websites - Useful BASIC Newsgroups - BASIC Compilers FINAL WORDS -NEWS------------------------------------------------------------------------- *** POWERBASIC 3.5 *********************************************************** Look, there's a new version of PowerBasic out... see www.powerbasic.com for more details. Unfortunately there's still no 100% compatibility with QB. Dave Navarro claimed in a recent post to alt.lang.basic that: "The fact of the matter is that less than 400 people in the history of our company have requested 100% compatibility with QuickBasic. Our market surveys show that what QuickBasic programmers want is not syntax compatiblity, but IDE compatiblity. The next major upgrade of the DOS compiler will include a complete re-write of the IDE which will incorporate many features which have been requested by QuickBasic programmers." So there you have it. PB costs $110 I think... (not a very well-researched article was it? ) *** BASIX ARTICLE READER ***************************************************** If you find reading this magazine as a text file a total pain, you can now read the various articles in a handy reader, programmed by Jakob Krarup. It's available for download at http://come.to/axe/basix. Features include the ability to extract BASIC code from an article and mouse support. Coming soon will be support for searching, making reading the Basix Fanzine easier than ever. -ARTICLES--------------------------------------------------------------------- *** TIMING, by Jakob Krarup (Jake@post5.tele.dk) ***************************** Hi I'm Jakob Krarup (Jake@post5.tele.dk), and I've been programming in QBASIC around 5 years now. I was going to switch completely to Visual Basic when I came across the BASIX Arcives on the net, and suddenly I knew - I was not alone - it was cult to do the QB thing = ) So I downloaded the nine issues of BASIX and read them thoroughly over and over, and my programs started improving drastically. So now I'd like to put something back into the newzine, since I've gotten so much from it. A lot of programs I find on the net use the FOR...NEXT loop to pause the game by merely counting, and then the programmer has added a comment along the lines: "'alter this if the program runs too slow/fast". There is a better way, which doesn't change speed according to the speed of the computer. Of course we could use the SLEEP command, but since most of the delays we're talking about are all below one second, this will not do. I usually store the timer in a variable of type single and then do a loop while the difference between the starting time and the current time hasn't passed the desired delay. Like this: Delay! = 0.5 'Set the delay (change the value to the desired length) StartingTime! = TIMER 'Store the starting time DO 'keep checking whether LOOP WHILE TIMER - StartingTime! < Delay! 'enough time has passed. This can easily be changed into a SUB: SUB DELAY (Delay!) StartingTime! = TIMER 'Store the starting time DO 'keep checking whether LOOP WHILE TIMER - StartingTime! < Delay! 'enough time has passed. END SUB This way you could just write Delay .5 in your code - and the sub takes care of the rest as simple as that. *** CUSTOMIZED FONTS, also by Jakob Krarup... ******************************** One of the things I've noticed on the net is that a lot of people see you as a low- or medium skilled Basic programmer until you have your own font in your programs. Well - after reading Alex Warren's article on binary numbers in BASIX issue 9 I decided to make one myself. If you don't feel at home in the binary numbers, please read Warren's article again before continuing. Truth to tell, I had already made a font editor that allowed you to draw a 6x8 pixels font, but the way I stored it was *very* simple (don't laugh!). The fontfile itself was opened with: OPEN "filename.ext" FOR OUTPUT AS #1 and then every pixel was written to the file as an integer (0 or 1) using the command: PRINT #1, ... this resulted in each pixel in the font taking up three bytes instead of one bit because PRINT #1 writes a string to the filenumber indicated and finishes it off with two ascii signs CR and LF. CR (ASCII value 13) is a 'Carriage Return' which means: go to the beginning of the line again, and LF (ASCII value 10) is a 'Line Feed' which means: go down a line. All these two values do is is to put the cursor on the next line, back at the left margin. Anyway, with 140 characters in the font, each character with 6x8 (48) pixels, and each of these written in a byte followed by the two CR + LF bytes - this would mean a whopping: 140 x 6 x 8 x 3 bytes = 20,160 bytes or more than 20 Kb for the font. If I could put this into a bit per pixel, it would mean 140 x 6 x 8 bits = 6,720 bits / 8 = 840 bytes or only 4.2 percent of the original. This I had to work on! Okay - to begin with, I had a pretty good way of numbering the characters in my font, because I simply used the ASCII character number 33 (the exclamation point) as my first letter, and then ended up with ASCII value 172 (the 1/4 or one quarter sign) as the last letter. That way I could deduct 33 from the ASCII value of a letter the program was to write and index the values in the font array. I skipped the first 32 characters as most of them are unprintable anyway - look at the ASCII table in the BASIC helpfile for yourself. While I was still editing the font, each bit would have an integer value that determined whether there would be a pixel or not. So in memory the font would be dimensioned DIM Font% (140, 6, 8) and since there wasn't need for much more memory this was the easiest, instead of encoding and decoding to and from binary while editing. My font looked like this bitwise: (Capital A) 0 1 2 3 4 5 Columns Rows 0 0 0 1 0 0 0 1 0 1 0 1 0 0 2 1 0 0 0 1 0 3 1 1 1 1 1 0 4 1 0 0 0 1 0 5 1 0 0 0 1 0 6 0 0 0 0 0 0 7 0 0 0 0 0 0 And to encode them from the Font% array to the binary mode I'd do it one column at a time, top down, by multiplying the digits with 2 to the power of the row they are in. So the columns would look like this: (remember it's top down) Column 0 Column 1 Column 2 0 * 2^0 = 0 0 * 2^0 = 0 1 * 2^0 = 1 0 * 2^1 = 0 1 * 2^1 = 2 0 * 2^1 = 0 1 * 2^2 = 4 0 * 2^2 = 0 0 * 2^2 = 0 1 * 2^3 = 8 1 * 2^3 = 8 1 * 2^3 = 8 1 * 2^4 = 16 0 * 2^4 = 0 0 * 2^4 = 0 1 * 2^5 = 32 0 * 2^5 = 0 0 * 2^5 = 0 0 * 2^6 = 0 0 * 2^6 = 0 0 * 2^6 = 0 + 0 * 2^7 = 0 + 0 * 2^7 = 0 + 0 * 2^7 = 0 ---------------- ---------------- ---------------- = 60 = 10 = 9 ================ ================ ================ and so on... The fontstoring array would be dimensioned: DIM FontArray AS STRING * 840 '140 letters with 6 columns each and I'd then store the ASCII values in a string array using the chr$(ASCII code). That way the six first bytes were the first letter, the six next were the second etc. Then I could save the font using the BINARY format: OPEN "filename.ext" FOR BINARY AS #1 PUT #1, 1, FontArray CLOSE #1 Easy - huh? I could load the font file the same way OPEN "filename.ext" FOR BINARY AS #1 GET #1, 1, FontArray CLOSE #1 and then write them to the screen using PSET. The writing algorithm would look up the letter, and check each bit by AND'ing with 2 to the power of the pixel position in the column. Text$ = "Hi there!" SCREEN 13 'go into graphics mode Xmargin% = 100 'Where should writing begin on screen Ymargin% = 50 ColorDesired% = 14 'here we are writing with yellow FOR Letter% = 1 TO LEN(Text$) 'We check each letter in the text. AsciiValue% = ASC(MID$(Tekst, Letter%, 1)) - 33 'First we find the ASCII value and subtract 33 'to find the first byte (column) in the letter IF AsciiValue% >= 0 AND AsciiValue% <= 140 THEN 'and see if it's in the font FOR X% = 0 TO 5 'Checks the Columns FOR Y% = 0 TO 7 'Checks the rows IF ASC(FontArray (AsciiValue% * 6 + X%)) AND 2^Y THEN 'We AND the column byte with 2^row PSET (Xmargin% + (Letter% - 1) * 6 + X%, Ymargin% + Y%), ColorDesired% ENDIF NEXT Y% NEXT X% END IF NEXT Letter% Unfortunately this is rather slow on older machines - and you can actually see the font being written. So I made a look-up-table of all the values 0 - 7 squared and used that when AND'ing instead of doing math every time a pixel was set. The table is dimensioned and initiated like this: DIM LookUpTable(8) as INTEGER FOR Counter% = 0 to 7 LookUpTable(Counter%) = 2^Counter% 'generates the numbers 1, 2, 4, 8, ... 128 NEXT Counter% The center three lines in the fontdrawing algorithm would look like this then: IF ASC(FontArray (AsciiValue% * 6 + X%)) AND LookUpTable(Y) THEN PSET (Xmargin% + (Letter% - 1) * 6 + X%, Ymargin% + Y%), ColorDesired% ENDIF This speeds up the drawing quite a bit on math-weak machines. Finally - make the font drawing routine into a sub by all means and just pass along X and Y coordinates, the string to be printed and a color. SUB Write (Xmargin%, Ymargin%, Text$, ColorDesired%) FOR Letter% = 1 TO LEN(Text$) 'We check each letter in the text. AsciiValue% = ASC(MID$(Tekst$, Letter%, 1)) - 33 'First we find the ASCII value IF AsciiValue% >= 0 AND AsciiValue% <= 140 THEN 'then see if it's in the font FOR X% = 0 TO 5 'Check each column FOR Y% = 0 TO 7 'Check each row IF ASC(FontArray (AsciiValue% * 6 + X%)) AND 2^Y% THEN PSET (Xmargin% + (Letter% - 1) * 6 + X%, Ymargin% + Y%), ColorDesired% ENDIF NEXT Y% NEXT X% END IF NEXT Letter% END SUB Hope you can use this information in making your own fonts! Jakob Krarup - Jake@post5.tele.dk. *** FRACTAL DIMENSIONS, by Razvan Caracas (catmin@math.math.unibuc.ro) ******* Dear Sir, I have seen that you are preparing an electronic journal about BASIC programming and consequently I have sent you a small programm whose purpose is to calculate fractal dimensions of linear signals. Yours sincerely, Razvan Caracas Bucharest University, Faculty of Geology, Mineralogy Department, 1, N Balcescu ave 70111 Bucharest Romania e-mail: catmin@math.math.unibuc.ro Linear singals fractal analysis The programm performs a fractal analysis of linear signals. It calculates the fractal dimension on the basis of a sampling function. The sampling function is: Y(n,l)(x) = ABS( f(x + l * dt) - f(x) ) ^ n, where n is a real constant, l is a real variable, x is the sampling point where the f(x) signal has been recorded. The average of the function Y(n,l)(x) over the range xmin - xmax gives the function: A(n,l). Then the A(n,l) power-law dependence of l is checked: A(n,l) = w * l ^ D, where w is a parameter. For n = 2 the exponent D is the real dimension of the signal. The input file is an ASCII file describing the signal values f(x) at each point x. The output consists of the fractal dimension, the exponent D, and an ASCII file with the logarithms of A(n,l) and l value, respectively. INPUT "Input file name: ", infile$ INPUT "Output file name: ", outfile$ INPUT "Sampling rate: ", dt INPUT "Power: ", n 'input data module OPEN infile$ FOR INPUT AS #1 DO WHILE NOT EOF(1) INPUT #1, a, b nrdata = nrdata + 1 LOOP CLOSE REDIM indata(nrdata, 2) OPEN infile$ FOR INPUT AS #1 FOR i = 1 TO nrdata INPUT #1, indata(i, 1), indata(i, 2) indata(i, 1) = i NEXT CLOSE 'calculation module lmax = INT(nrdata / dt) - 1 REDIM s(lmax, 2) REDIM lns(lmax, 2) FOR l = 1 TO lmax - 1 x = 0 suma = 0 DO WHILE x + l * dt < nrdata - dt x = x + 1 suma = suma + ABS(indata(x + l * dt, 2) - indata(x, 2)) ^ n LOOP s(l, 1) = l s(l, 2) = suma / x lns(l, 1) = LOG(l) lns(l, 2) = LOG(suma / x) NEXT 'output module OPEN outfile$ FOR APPEND AS #1 FOR i = 1 TO lmax PRINT #1, lns(i, 1), lns(i, 2) NEXT 'fit module FOR i = 1 TO lmax s1 = s1 + lns(i, 2) s2 = s2 + lns(i, 1) s3 = s3 + lns(i, 1) * lns(i, 2) s4 = s4 + lns(i, 1) ^ 2 NEXT IF s4 = s2 ^ 2 THEN PRINT "Fractal dimension infinite" ELSE m = (s1 - s2 * s3) / (s4 - s2 ^ 2) PRINT "Fractal dimension is : ", ABS(m) END IF *** GRAPHICS IN QBASIC TUTORIAL (PART 1) ************************************* by "Hacker" aka Damian Nikodem (Hacker@alphalink.com.au) ********************* Intro: I am assuming that you HAVE some experience in basic programing. If you dont then dont bug me with a &H7FFF (32767) E-mail messages about what is a integer. Now in this tutorial I will show you how to load(and understand!) many image formats, speed up nearly ALL of your graphics routines, and nearly any other aspect of graphics in BASIC. Now onto the tutorial! Palette: The palette is a series of numbers where the values of the colors is kept. Or in other words if you change the palette you can change the colors in a image. So if you want to draw a green gradient in Vga mode 13h (screen 13) you would have to change the palette because there isnt enough green's in the existing palette. Now you may be thinking that this is hard to do but in reality it is EXTREMELY easy. In fact it can be done in just 4 commands: ' start CODE OUT &H3C8, col OUT &H3C9, red OUT &H3C9, green OUT &H3C9, blue ' end CODE Now, the value that should be inside `col' is the color that you want to change, the value in `red' it the ammount of RED you want in the color you want to change,`green' and `blue' are the same execpt that they are diffrent colours. The color values CAN'T be over 63 or it will have some intresting errors. This code can be cycled incrementing one or more values to produce some cool effects (red flashing screen)or this can be used just once to load a image with diffrent colors. Now there is a way to save and read palette's quickly and it has (nearly) become a standard ammong basic programers here is the sub routines to load and save the .PAL files ' start CODE SUB file2pal (file$) OPEN file$ FOR BINARY AS #1 r$ = " " g$ = " " b$ = " " FOR x% = 0 TO 255 GET #1, , r$: r% = ASC(r$) GET #1, , g$: g% = ASC(g$) GET #1, , b$: b% = ASC(b$) CALL pal(x%, r%, g%, b%) NEXT x% END SUB SUB getpal (Colour%, Red%, Green%, Blue%) OUT &H3C7, Colour% Red% = INP(&H3C9) Green% = INP(&H3C9) Blue% = INP(&H3C9) END SUB SUB pal (Colour%, Red%, Green%, Blue%) OUT &H3C8, Colour% OUT &H3C9, Red% OUT &H3C9, Green% OUT &H3C9, Blue% END SUB SUB pal2file (file$) OPEN file$ FOR OUTPUT AS #1 FOR x% = 0 TO 255 CALL getpal(x%, r%, g%, b%) PRINT #1, CHR$(r%); CHR$(g%); CHR$(b%); NEXT x% CLOSE #1 END SUB 'end CODE Now it is simple to use these routines just add pal2file ("palette.pal") to your code to send a copy of the palette to a file called `palette.pal' and to load a saved palette you just use file2pal ("palette.pal") to load palette.pal now that you understand this i'll go onto a FAST routine Fast Graphics: Have you notaiced that PSET is very slow! well you can do the same job by writing to memory execpt it is a LOT faster here is a small bit of code that writes color 30 to a (10,10) 'start CODE screen 13 def seg= &HA000 ' Tells the computer to point to video memory x = 10 ' The X position of the pixel on the screen y = 10 ' The Y position of the pixel on the screen col = 30 ' The color of the pixel poke (y*320) + x, col ' Puts the pixel on the screen 'end CODE The math on the last line is quite simple. The screen is simple to understand this is a small representation of the screen every box is one pixel and the number inside that box is the memory address of the pixel +------+------+------+------+------+------+... | 01 | 02 | 02 | 04 | 05 | 06 | +------+------+------+------+------+------+ | 321 | 322 | 323 | 324 | 325 | 326 |... +------+------+------+------+------+------+ | 641 | 642 | 643 | 644 | 645 | 646 |... +------+------+------+------+------+------+ . . . . . . . . . . . . . . . . . . . . . because VGA mode 13h (screen 13) has 320 pixles on the horozontal axis we multiply y by 320 to figure out which line to write and we add x to figure out which column the pixel is! In the next part I will teach you about the PCX format (if alex is shocked how big that one is he will DIE :] when he sees the size of the GIF tutorial [or .JPG if I have the time]) - Hacker (Hacker@alphalink.com.au) Note: DO NOT E-MAIL ME ABOUT SPELLING MISTAKES OR ANY OTHER GRAMMER ERRORS *** MAKING LIBRARIES, by Alan Copeland (HotDogBoy5@aol.com) ****************** You've heard all about them, seen them all over the internet, and you maybe have even downloaded and used a couple. What are they? Libraries, of course! A Library is an essential programming concept/techneqe that can and will make programming easier, same lot of time, and make you code quicker, tighter, and more organized. I'll try and explain how to make and use these facinating things, and make it as painless as possible. Unfortanitly, you will need Quickbasic 4.5, and not just the 1.1 that comes with DOS. Now that you have the QB45, lets go. Before you can make librarys, you have to understand what they are. In my little one horse town in the burbs of Philly, they just built a new public library. It's nice and big, and very useful. Basicly, people write books for all purposes, and put them in it. Then anyone can go right in, quickly get the book they need, and leave. The smart people out there might have guessed that this is the perfect analogy for a programming library. It's a big file, and in it has a bunch of subroutines. You program delves right into it, finds the subroutine it needs, uses it, and leaves. How is aone of these better than subroutines in a regular program? I'll tell you, just because I can make a bulleted list. The subs are not in the main code, which keeps it smaller. By putting subs into a library, you can easily find them and use them again for other programs You can make renevue generating useful librarys to sell to other programers Now that you know what one is, how do you use one? First, you need to get one. Get onto any site with QB files, and they are bound to have a library of mouse routines, or a Sound Blaster Library. Download one, and you should get some files, which consist of file ending in .QBL, a file ending in .LIB, and probably a Readme file. The QLB file is for writing and testing, and can be used directly by the QB interpreter. The LIB file is for the compiler, so you can compile your programs. The Readme file shouold contain a list of all the routines, and how to use them. Copy the QLB and LIB file into your QB directory, and start Qbasic with the following syntax: QB /L YOURLIBNAME.QLB Qbasic should start up without a hitch, but not flash the opeing screen. When you browse around, you should notice nothing differnt. Theres no subs in the sun menu, no extra menus, no extra anything. Trust me, the routines are there. But how to use them? Use the regular sub syntax. You can now start to see how this can greatly influence program code. For example, say you had a game, where when the user pressed the left key, it did all the stuff to run left. Put all that in a library, with a routine named RUN, and have both directions in there, pass argument to it, and you can now do it in one statement by haveing the statement "...THEN CALL RUN(LEFT)". It looks better than other things. So now that you know what they are, and you know how to use them, your all pshyced up to go make one! Thats the spirit! Everyones raring to go! Making a library I'm in the jazz band at my school. Our band director is named Mr. Baron. He says lots of stuff, like "dude", "cool", "wimp-er-doodle", and "cheese and crackers!". Lets say, hypotheticly, that I wanted to make a library that could say the sounds of Mr. Baron when called apon. So lets start. Start QB with no extra syntax, and make a new SUB called "dude". In it, type, PRINT "Mr. Baron often says dude, Dude." Make another SUB called "cool", and in it type PRINT "Cool! Mr Baron says Cool alot!" Make one more sub thats named "wimp". Type in it PRINT "Don't be such a wimp-er-doodle when you play!" Now go back to the main module. Make sure your subs work properly (they should just display mesages), and save your program as BARON. Next, on the RUN menu, there is a chioce that says Make library. Choose this, and in the quicklibrary name box, type in BARON. The Library comiler should go crazy and do its thing, and return you to your program. Congradulations! You've made a librarry! Now exit QB, and start it with the syntax: QB /L BARON.QLB MRB.BAS In your new program, typein the following code: DO CLS ? "Barons Speech Menu!" ? "1. Say Cool!" ? "2. Say Dude!" ? "3. Say Wimp-er-doodle" Input choice$ IF choice$ = "1" Then CALL cool IF choice$ = "2" Then CALL dude IF choice$ = "3" Then CALL wimp Else Exit do End if LOOP END Save this, and test out the new "Baronisms menu". If everything works out, then the menu should work totally perfect. You know know how to work librarys, how to make them. Now was it as hard as you thought? Anyway, I hope you had as much fun reading as I did writing this. Oh well. One final note - If you plan to distribute your librarys, then make sure that you include the LIB, the QLB, and a TXT file containg documentation on ALL the routines. So start making librarys! -PROGRAMS--------------------------------------------------------------------- *** 4DD.BAS, by "Anna" (q.dao@student.murdoch.edu.au) ************************ "Anna" [not the real name of this person, maybe he/she wants to remain anonymous? :) -ed] writes: ...here is some basic code for that basic mag. It is a graphic demo. [ed's note: you'll probably have word-wrapping trouble with the DRAW line - make sure it's all in one big piece before running the program] SCREEN 0, 0, 0: CLS : SCREEN 13: PALETTE 0, 5 * 65536: CL& = 65536 + 256 FOR X% = 1 TO 31: PALETTE X%, (X% MOD 64) * CL&: NEXT FOR X% = 32 TO 63: PALETTE X%, (64 - (X% MOD 64)) * CL&: NEXT FOR N% = 64 TO 127: PALETTE N%, (N% - 64) * 65536: NEXT FOR Y% = 80 TO 199: C% = C% + 1 LINE (0, Y%)-(319, Y% + C%), (C% / 2) + 64: LINE (0, Y%)-(319, Y% + C% + 1), (C% / 2) + 64 LINE (0, Y%)-(319, Y% + C% + 2), (C% / 2) + 64: LINE (0, Y%)-(319, Y% + C% + 3), (C% / 2) + 64 LINE (0, Y%)-(319, Y% + C% + 4), (C% / 2) + 64 NEXT DRAW "bm160,90c255bl75u50r15d40r15u20r15d20r20d10l20d25l15u25l30br80bd25u75r35f20d35g20l35be15u45r15f10d25g10l15bm161,90c255bl75u50r15d40r15u20r15d20r20d10l20d25l15u25l30br80bd25u75r35f20d35g20l35be15u45r15f10d25g10l15bm162,90c255bl75u50r15d40r15u20r15d20r20d10l20d25l15u25l30br80bd25u75r35f20d35g20l35be15u45r15f10d25g10l15bm163,90c255bl75u50r15d40r15u20r15d20r20d10l20d25l15u25l30br80bd25u75r35f20d35g20l35be15u45r15f10d25g10l15" PAINT (90, 70), 255: PAINT (173, 70), 255 FOR Y% = 40 TO 119: FOR X% = 80 TO 229 C% = C% + INT(RND * 3): c1% = POINT(X% + 1, Y% - 1): IF c1% > 63 THEN c1% = 0 C% = (c1% + C%) / 2: IF POINT(X%, Y%) = 255 THEN PSET (X%, Y%), C% NEXT: NEXT LOCATE 3, 13: COLOR 255: PRINT "4th Dimension" FOR Y% = 13 TO 25: FOR X% = 90 TO 210: C% = C% + INT(RND * 3): c1% = POINT(X% + 1, Y% - 1): IF c1% > 63 THEN c1% = 0 C% = (c1% + C%) / 2: IF POINT(X%, Y%) = 255 THEN PSET (X%, Y%), C% + 10 NEXT: NEXT *** NEWTIMER.BAS, by "Hacker" aka Damian Nikodem (Hacker@alphalink.com.au) *** Hacker writes: here is a small program that changes the pit clock's refresh rate DECLARE SUB settimer (frequency!) ON TIMER(1) GOSUB t1 TIMER ON settimer (1000) CLS DO LOOP UNTIL INKEY$ <> "" settimer (1) SYSTEM t1: z = z + 1 PRINT z RETURN SUB settimer (frequency) Counter = &H1234DD / frequency OUT &H43, &H34 OUT &H40, Counter MOD 256 OUT &H40, Counter / 256 END SUB -FROM THE NEWSGROUPS---------------------------------------------------------- This is a new section where, basically, I put useful Usenet postings into the fanzine. I hope you find them useful. Most of these have been reproduced here with permission of the author. *** FOR THOSE OF YOU INTERESTED IN BASIC COMPILERS *************************** From: "John D. Morrison" Newsgroups: alt.lang.basic Subject: For those of you interested in Basic Compilers. Date: 1 Oct 1997 14:06:55 GMT There are two new Basic compilers out, which have been referred to several times in recent posts on basic newsgroups. They are GFA Basic, and OmniBasic. For curiousity sake, I downloaded trial versions of both of them to check out. Both of them will create .EXE's, but OmniBasic requires you to have DJGPP as well. It compiles your basic code to low-level C code, which it then passes to DJGPP (Gnu C++) to compile. GFA Basic is somewhat simpler to use, and comes with both an interpreter and a compiler. The only drawback to the compiler is that it creates .EXE's which require a run-time module, Ala Quick Basic. Of the two, I'd recommend GFA basic for beginners, simply because you don't need a separate C compiler to use it. The interface is a little clunky, but it works, and it does compile ! Of course, the trial versions both limit you somehow. Omni Basic limits the size of the symbol table, which means you can only have a limited number of variables. GFA Basic limits you to 1000 lines of code per program. But for a beginner, that should be enough to get started. John Morrison *** READING TWO KEYS ********************************************************* From: cadwright@aol.com (CadWright) Newsgroups: alt.lang.basic Subject: Re: **** reading two keys Date: 7 Oct 1997 15:30:53 GMT In article <01bcd23d$ad136a20$5a180ed0@bryan>, "roqu" writes: >i need a way (exampe would be helpful) to read in 2 keys from the keyboard. >for instance, how could i tell if the user is pressing (not on numeric pad) >up arrow and at the same time left arrow, for diagonal purposes? i cant >even remember how to do this in c, im pretty sure its input from the >keyboard buffer at H60 and some arrays involved. >anything would be of great help You've just about got it, use INP to get which keys are being pressed or released and use an array to hold the state of the keys - dim KeyArray(127) as integer i = inp(&h60) if i <128 then 'pressing a key KeyArray(i) = -1 else 'releasing a key KeyArray(i-127) = 0 end if if KeyArray( 75 ) = -1 then 'pressing the left key if KeyArray( 72 ) = -1 then 'pressing the up key etc. Hmm, I've just typed that from memory so it may not be 100% correct :-) TTfn, Craig___ *** DETERMINING HOME DIRECTORY *********************************************** From: christy.gemmell@islington-bbs.com (Christy Gemmell) Newsgroups: alt.lang.basic Subject: Determining 'home' directory Date: Thu, 06 Nov 1997 14:03:00 GMT mighty@coosavalley.net enquired... TR> Does anyone know how to determine in QB 4.5 what directory > a compiled .EXE program resides in when it is executed? Yes Tim, this program will do exactly that. Feel free to adapt it for your own use. Be aware though that it only works as expected in a compiled .EXE file. If you run it in the QuickBASIC IDE it will return the path of QB.EXE *not* your source code file Christy --- cut here ---------------------------------------------------------------- ' PATHNAME.BAS reports the drive and directory path the current program ' has started up from and the name of the program itself. ' ' $INCLUDE: 'QB.BI' ' DECLARE FUNCTION PathName$ (ProgName$) DIM SHARED Regs AS RegType ' To hold register values b$ = "" a$ = PathName$(b$) PRINT a$, b$ END FUNCTION PathName$ (ProgName$) Regs.ax = &H6200 ' DOS Service 98 INTERRUPT &H21, Regs, Regs ' - find PSP segment DEF SEG = Regs.bx ' Segment of current program EnvSeg& = PEEK(&H2C) + PEEK(&H2D) * 256& ' Get environment pointer DEF SEG = EnvSeg& ' Environment segment i% = 0 ' Shuffle DO ' through DO ' environment ThisByte% = PEEK(i%) ' strings i% = i% + 1 ' looking LOOP WHILE ThisByte% ' for two ThisByte% = PEEK(i%) ' successive i% = i% + 1 ' null LOOP WHILE ThisByte% ' bytes i% = i% + 2 ' Skip over some junk ProgName$ = "" ' To hold the program name DO ' Read ThisByte% = PEEK(i%) ' each IF ThisByte% THEN ' character ProgName$ = ProgName$ + CHR$(ThisByte%) ' of program END IF ' name until i% = i% + 1 ' we find LOOP WHILE ThisByte% ' null byte DEF SEG ' Restore default segment l% = LEN(ProgName$) ' Did we find anything? IF l% THEN ' If so DO ' scan c$ = MID$(ProgName$, l%, 1) ' backwards IF c$ = "\" THEN EXIT DO ' looking l% = l% - 1 ' for the LOOP WHILE l% ' path END IF ' delimiter IF l% THEN ' Seperate PathName$ = LEFT$(ProgName$, l%) ' directory ProgName$ = MID$(ProgName$, l% + 1) ' path ELSE ' from PathName$ = "" ' program END IF ' name END FUNCTION --- and here ---------------------------------------------------------------- * 1st 2.00 #323 * Father forgive me, for I have GOTOed. *** fINPUT FOR QB ************************************************************ [Ed's note: It's a powerful input routine for QB, much better than that INPUT command we're all used to.] From: d83@ath.forthnet.gr (Don Schullian) Newsgroups: alt.lang.basic,comp.lang.basic.misc Subject: fInput for QB Date: Fri, 26 Dec 1997 14:46:45 GMT DECLARE FUNCTION fInput% (D$, Row%, Col%, VisLen%, MaxLen%, Mask$, Fgrnd%,Bgrnd%) DECLARE FUNCTION fInsertKey% () DECLARE FUNCTION fGetKey% () CONST ENTERkey% = &HD CONST ESCkey% = &H1B CONST LEFTkey% = &H4B00 CONST RIGHTkey% = &H4D00 CONST HOMEkey% = &H4700 CONST ENDkey% = &H4F00 CONST BkSPCkey% = &H8 CONST DELkey% = &H5300 CONST INSkey% = &H5200 CLS B$ = "This is a test" Exet% = fInput%(A$, 10, 10, 5, 5, "0123456789 ", 0, 7) Exet% = fInput%(B$, 11, 10, 30, 50, "", 0, 7) Exet% = fInput%(C$, 12, 10, 1, 1, "YyNn", 0, 7) LOCATE 1, 1 PRINT ">>"; A$; "<<" PRINT ">>"; B$; "<<" PRINT ">>"; C$; "<<" FUNCTION fGetKey% DO G$ = INKEY$ LOOP UNTIL LEN(G$) > 0 IF LEN(G$) = 1 THEN fGetKey% = ASC(G$) ELSE fGetKey% = CVI(G$) END IF END FUNCTION FUNCTION fInput% (D$, Row%, Col%, VisLen%, MaxLen%, Mask$, Fgrnd%, Bgrnd%) DIM Item AS STRING * 256 Item$ = D$ Cpos% = 1 Opos% = 1 OldFore% = SCREEN(Row%, Col%, 1) OldBack% = (OldFore% \ 16) OldFore% = (OldFore% AND 15) Inzert% = fInsertKey% FirstKey% = -1 COLOR Fgrnd%, Bgrnd% DO LOCATE Row%, Col%, 0 PRINT MID$(Item$, Opos%, VisLen%) LOCATE Row%, (Col% + Cpos% - Opos%), 1 G% = fGetKey% SELECT CASE G% CASE 32 TO 254 C$ = CHR$(G%) IF (LEN(Mask$) = 0) OR (INSTR(Mask$, C$) > 0) THEN IF FirstKey% THEN Item$ = "" IF Inzert% THEN IF Cpos% = 256 THEN MID$(Item$, Cpos%) = C$ ELSE MID$(Item$, Cpos%) = C$ + MID$(Item$, Cpos%) END IF ELSE MID$(Item$, Cpos%, 1) = C$ END IF IF MaxLen% = 1 THEN G% = ENTERkey% EXIT DO END IF IF Cpos% < MaxLen% THEN Cpos% = Cpos% + 1 IF Cpos% > VisLen% THEN Opos% = Opos% + 1 END IF END IF CASE ESCkey%, ENTERkey% ' ESCAPE & ENTER EXIT DO CASE BkSPCkey% ' BkSPC IF Cpos% = 2 THEN Item$ = MID$(Item$, 2) Cpos% = 1 ELSEIF Cpos% > 2 THEN G$ = LEFT$(Item$, Cpos% - 2) Item$ = G$ + MID$(Item$, Cpos%) Cpos% = Cpos% - 1 IF Cpos% < Opos% THEN Opos% = Opos% - 1 END IF CASE DELkey% ' DELETE IF Cpos% = 1 THEN Item$ = MID$(Item$, 2) ELSEIF Cpos% < 256 THEN G$ = LEFT$(Item$, Cpos% - 1) Item$ = G$ + MID$(Item$, Cpos% + 1) END IF CASE INSkey% ' INS Inzert% = fInsertKey% CASE LEFTkey% ' LEFT ARROW IF Cpos% > 1 THEN Cpos% = Cpos% - 1 IF Cpos% < Opos% THEN Opos% = Opos% - 1 END IF CASE RIGHTkey% ' RIGHT ARROW IF Cpos% < MaxLen% THEN Cpos% = Cpos% + 1 G% = (Cpos% - Opos% + 1) IF G% > VisLen% THEN Opos% = Opos% + 1 END IF CASE HOMEkey% ' HOME Cpos% = 1 Opos% = 1 CASE ENDkey% ' END FOR Cpos% = MaxLen% - 1 TO 1 STEP -1 IF MID$(Item$, Cpos%, 1) <> " " THEN EXIT FOR NEXT Cpos% = Cpos% + 1 IF Cpos% <= VisLen% THEN Opos% = 1 ELSE Opos% = Cpos% - VisLen% + 1 END IF END SELECT FirstKey% = 0 LOOP IF G% <> ESCkey% THEN D$ = LEFT$(Item$, MaxLen%) D$ = LTRIM$(RTRIM$(D$)) END IF Item$ = D$ COLOR OldFore%, OldBack% LOCATE Row%, Col%, 0 PRINT LEFT$(Item$, VisLen%) fInput% = G% END FUNCTION FUNCTION fInsertKey% DEF SEG = 0 I% = (PEEK(1047) > 127) DEF SEG IF I% = 0 THEN LOCATE , , , 12, 13 ELSE LOCATE , , , 6, 13 fInsertKey% = I% END FUNCTION -LETTERS---------------------------------------------------------------------- *** FANZINE TEXT FORMAT, from Bart Veerman *********************************** Hi Alex, I just downloaded the latest Fanzine text files. When I tried listing them they looked funny and rewrote them to look readable on the screen. '---------------------------------------------------------------------- ' FANZREDO.BAS ' The Fanzine text files for some reason has only line feeds at the end ' of a line. To view them properly in a text editor you need to have a ' carriage return as well - CHR$(10)+CHR$(13). The program is based on ' a file copy routine from the book PC Basic Techniques & Utilities by ' Ethan Winer. '---------------------------------------------------------------------- CLS : DEFINT A-Z OPEN "basix09.txt" FOR BINARY AS 1 'open file to read FileSize& = LOF(1) 'how big is it? OPEN "basix09!.txt" FOR OUTPUT AS 2 're-writen file DO 'main DO IF FileSize& > 4096 THEN 'process 4K chunks Chunk = 4096 ELSE Chunk = FileSize& 'last chunk might be smaller END IF Chunk$ = SPACE$(Chunk) 'read this much GET #1, , Chunk$ 'read it from disk DO WHILE INSTR(Chunk$, CHR$(10)) 'chunk has a line feed? a = INSTR(Chunk$, CHR$(10)) 'where is it? a$ = LEFT$(Chunk$, a - 1) 'drop the line feed PRINT a$ 'show sentence on screen PRINT #2, a$ 'write sentence to new file 'CR+LF automatically written Chunk$ = MID$(Chunk$, a + 1) 'chop this sentence LOOP 'no more line feeds FileSize& = FileSize& - Chunk 'this much left-to-do LOOP WHILE FileSize& 'main DO CLOSE 'close up shop END 'outa here Thanks for putting it together, it's been helpful on several occasions. I do have a question I'm hoping you can ask in the next edition. With all the great stuff about SB sound card programming, I'm still trying to fond out how to get raw audio frequencies to the SB. I'd like to get the same 37 to 32KHz to sound through it. QB Example: sound 10000,1 '1 second of 10,000 Hz. sound Your help much appreciated and all the best, Bart Veerman Ancaster, Ontario Canada. Bart Veerman Hamilton, Ontario Canada. Thanks for the program - I haven't had any other reports of this problem in any of the fanzine issues but I've put it in just in case. As for the SB question, I have no idea - if anyone does please email Bart and/or the fanzine. Bart's email address is Bart@mail.globalserve.net. -ed. -INTERNET RESOURCES----------------------------------------------------------- *** GETTING THE FANZINE ****************************************************** - Websites The Basix Fanzine is now available at this easier-to-remember URL: http://come.to/axe/basix The Basix Fanzine Interactive Library will be at: http://www.geocities.com/SiliconValley/Horizon/2451/ (note that the Library is not there at the moment) - Newsgroups The Basix Fanzine is posted when it is released to alt.lang.basic, alt.lang.powerbasic, comp.lang.basic.misc and microsoft.public.basic.dos. If you want it posted to any other BASIC newsgroups then please let me know. - Mailing List To get the Fanzines as they are released, join Tony Relyea's mailing list by sending an email to the new address of fanzine@vt.edu with subject "subscribe basix-fanzine" *** USEFUL BASIC WEBSITES **************************************************** New addresses for sites featured before in the fanzine are marked with a !. Totally new sites never featured before are marked with a *. WEBSITES (http://) : -PowerBASIC www.powerbasic.com -QBasic.com www.qbasic.com -The Programmer's Page www.professionals.com/~peterp/ !ABC come.to/abcpackets -PowerBasic Archives pitel-lnx.ibk.fnt.hvu.nl/~excel/pb.html -Tim's QuickBasic Page www.geocities.com/SiliconValley/Heights/8967/ -QBasic Programming Corner www.geocities.com/TheTropics/9964/qbasic.html -Zephyr Software (SVGA Library) www.zephyrsoftware.com -The QBasic Site hem.passagen.se/hedsen *MOD Library www.fortunecity.com/millenium/celesteville/23/index.html *Ralf Brown's Interrupt List www.ctyme.com/rbrown.htm *DMAPLAYH.BAS www.ocf.berkeley.edu/~horie/project.html *The QuickBasic Enhanced Programming Page [! see below !] www.geocities.com/SiliconValley/Lakes/7303/ *QMIDI www.primenet.com/~merlin57/qmidi/ !Basix Fanzine come.to/axe/basix -Alex Warren's BASIC page www.users.globalnet.co.uk/~dewarr/basic.htm -Basix Fanzine Interactive Library www.geocities.com/SiliconValley/Horizon/2451/ FTP SITES (ftp://) : -PCGPE (PC Games Programmers' Encyclopaedia) x2ftp.oulu.fi/pub/msdos/programming/gpe -Blood 225's BASIC stuff users.aol.com/blood225 THIS MONTH'S SELECTION OF GOOD SITES: Two good sites this month that may be of interest to you: - The QuickBasic Enhanced Programming Page: Nice site featuring QB games, libraries and utilities. WetSpot is a game that featured in the ABC Packets some time ago - check out this site to see the progress of WetSpot II, plus a number of other projects. From what I can tell from the screenshots, it looks great! There is also a big page full of links to useful libraries such as the Blast! libraries, EMS library, timer handlers, and more. For all this and more, visit: http://www.geocities.com/SiliconValley/Lakes/7303/ - QMIDI QMIDI is currently in version 3.0 and is a library that allows you to play MIDI files from most BASICs - even QBasic! It will let you play MIDIs in the background too - well worth looking at if you want music in your games. The URL is: http://www.primenet.com/~merlin57/qmidi/ MORE GOOD WEBSITES AT: http://www.users.globalnet.co.uk/~dewarr/coolsite.htm If you own or know of a good BASIC website, please let me know and I'll add it to the list. *** USEFUL BASIC NEWSGROUPS ************************************************** There are four BASIC newsgroups that I know of, if anyone knows of any others please let me know: alt.lang.basic alt.lang.powerbasic comp.lang.basic.misc microsoft.public.basic.dos *** BASIC COMPILERS ********************************************************** PLEASE stop asking where to get BASIC on the various newsgroups! You will not get a free copy easily, and it's very tedious when the same answer is given to the question "where can I get BASIC" every single day. For this reason, below is a list of websites where you can purchase various BASICs and get your programs compiled: QuickBASIC, PDS 7.x, VBDOS, etc.: MS don't sell these any more but you can still find copies at: http://www.wdn.com/ems/oldtools/ms.htm http://www.provantage.com PowerBASIC: Perhaps the best BASIC to get if you're going to buy it, as this is still being supported. Go to www.powerbasic.com for information. If you want to compile very few programs which have been made using QBasic, and don't want to shell out $110 for PB, you can pay $5 a time for compiling at http://members.aol.com/qbasicnow. Email qbasicnow@aol.com for more information on this. If you're mean/broke and don't want to shell out any cash, QB4.5 can be downloaded from various websites though it's not strictly legal... in fact, it's not legal at all and Microsoft might get rather annoyed with you. However, given the age of QB, MS *probably* don't mind *that* much and would probably turn a blind eye as they have more important things to be getting on with, like making new operating systems that run slower than ever before. [I don't condone software piracy though so please don't moan at me ] If you know of any other compilers or would like to advertise yours here, send an email to basix@dewarr.globalnet.co.uk, or post a message on one of the BASIC newsgroups and hope that I see it. -FINAL WORDS------------------------------------------------------------------ Thanks to the following for their help with this issue: - Razvan Cracas - Jakob Krarup - "Anna" - "Hacker" aka Damian Nikodem - Bart Veerman - Alan Copeland ...and to the following for their wonderful newsgroup posts that I've reproduced here: - John D. Morrison - CadWright - Christy Gemmell - Don Schullian ...and anybody else who I've forgotten (I haven't have I?) NEXT ISSUE: I hope to have issue 11 done by July though preferably I will have it done much sooner than that. I already have part 2 of Hacker's graphics tutorial on PCX files and that will be included, but apart from that I have no idea what will be in it - so if you'd like to donate some source code or perhaps write an article, please email basix@dewarr.globalnet.co.uk - thanks in advance! Thanks for reading, and happy programming. Alex Warren, 29th March 1998