-IMPORTANT NOTE---------------------------------------------------------------- NOTE: Issues 1-8 of the Basix Fanzine were edited by Peter Cooper. Issues 9-13 of the Basix Fanzine were edited by Alex Warren. The new editor of the Basix Fanzine is David Groulx and the addresses for the fanzine are: ARTICLES: Basix_Fanzine@yahoo.com OTHER ENQUIRIES ETC.: Basix_Fanzine@yahoo.com WWW ADDRESS: http://www.come.to/basixfanzine Please use these addresses in place of the out-of-date addresses in the Fanzine below. David Groulx April 1999 ------------------------------------------------------------------------------- [Basix Internet BASIC Fanzine]- - - - - - - - - - - - - - - - - - - - - -, ,' Issue 8 - The Mag for BASIC Programmers..... created by Peter Cooper `, Ý`- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -/Ý Ý Ý Ý Welcome to the eighth issue of the BASIC Fanzine, once again there has Ý Ý been a slight delay in the appearance of this zine. The zine seems to Ý Ý appear bi-monthly at the moment. This is partially due to a lack of any Ý Ý articles code etc and also due to me. Ý Ý Ý Ý This time around we have some great new code for you to drool over plus Ý Ý the continuation of the 3D Series.. The letters section is now back and Ý Ý there are a couple of reviews to read too. Ý Ý Ý Ý Whatever the new year brings you, may it be a good one and I hope you Ý Ý enjoy reading the eighth issue of the zine.. Enjoy.. Ý Ý , `-------------------------------------------------------------------------' =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Contents Page =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Series \ Tutorials ~~~~~~~~~~~~~~~~~~ 1.1 - 3D Programming (part 2) - Continuing the series - PB\(QB poss) Regulars ~~~~~~~~ 2.1 - Letters - Your questions, views etc - All 2.2 - References - Lots of new web sites! - All 2.3 - NEWS! - News from the Basic world - N/A Code ~~~~ 3.1 - Copy Routine - Copying routine - QB(asic) 3.2 - 18BIT GFX in PB!! - Exclusive 18 Bit Routines - PB 3.3 - Font Placement - Reading font data from ROM - QBasic Reviews ~~~~~~~ 4.1 - LikED Review - An alternative PB editor - PB 4.2 - Site of the Issue! - New series surfing the web - All Admin\The End ~~~~~~~~~~~~~ 5.1 - Contact - Getting the zine, mailing - All 5.2 - And in the end... - Issue 8 is now over - All +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [1.1] - 3D Programming (part 2) Ý Written by Christian Garms +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ --------------------------------------- / / | ---------------------------------------- | 3D Graphics in BASIC - Part II.1: Epilog / ---------------------------------------- It sounds strange to begin with an epilog but I have to explain some real important things about the listing PYRAMID.BAS in the last part: 1. You only have to calculate the edges of a polygon. In the case of the pyramid you only have to calculate FOUR (!!!) points. The rest will do the LINEs. This is very good because it reduces the amount of calculations to a minimum and also, of course, the amount of cpu usage. 2. You must have an exact represantation of your 3D object. In our case of the pyramid this is very simple. There are only four points. The definition of the object is located in the DATAs. You need in general a DATA statement for the points and a DATA statement for the connectivity list. The connectivity list will instruct the program to draw the right lines to the right points. You must determine every edge exactly of any given 3d object you want to display. This is very time consuming and you can only create smaller objects with a pencil and a paper sheet. For 'bigger' objects (more points) you need a special editor. ----------------------------------------------- / / | ------------------------------------------------ | 3D Graphics in BASIC - Part II.2: 3D Animations / ------------------------------------------------ In PYRAMID.BAS there is only one single picture of a simple object. Boring, isn't ? The real 3D effect will only show up if the object will be animated like rotating around an axis or moving in real time. So I want you to show how to get this 'pyramid' into action. But tons of theory first ... To make understanding easier for this relative difficult subject because this part is like "Formula Jones and The Raiders of the lost Arc" and you could be easily get lost somewhere in the Amasinus I'll give you an overview of what to do: 1. 3D animations - and of course, animations in general - need the double buffering technique. That's a common used method of displaying and generating pictures simultaneously on different screen (often done by choosing different memory locations of the displaying screen and the drawing screen). If you would display and draw the picture on the same screen (the same memory location), the picture might become flickery. With the double buffering technique - and eventually waiting for the vertical retrace interrupt - the animated graphics looks very smooth. 2. Rotating, Scaling and Moving of 3D points could be done with matrix operations. Because matrix operations aren't a simply matter of fact at all I'll explain it here in this article but limited for our purpose. When you've worked through this stuff (it's a very thick formula thicket - have you got your machet right by your hand ?) you will see the advantages of this mathematical technique. ------------------------------------------------- / / | -------------------------------------------------- | 3D Graphics in BASIC - Part II.3: Double Buffering / -------------------------------------------------- Double buffering is a simple matter of fact. You only need two screens or pages in any location of the memory. The Video ram is mostly preferred because of higher perfomance (you must not copy the pages to the video ram from the memory anymore). A general algorithm for the Double Buffering technique is as follows: 1. Show the "display" page, hide the "draw" page 2. Clear "draw" page 3. Various Drawing operations in the "draw" page 4. Wait for vertical rectrace 5. Switch "display" and "draw" page The listing II-3.1 is in example for a simple demo of double buffering. The compiled program will show a rectangle that has four moving corners with different speed and direction. ************************************************************************** ' Double Buffering Demo ' (C)) 1996 by Ch. Garms ' Type declarations TYPE pixel x AS INTEGER y AS INTEGER END TYPE ' Some Constants %NOPE = 0 %UP = 1 %DOWN = 2 %PORT = 4 %STARBORD = 8 ' Variable declarations DEFINT a-z DIM r(3) AS pixel ' rectangle points DIM d(3) AS pixel ' direction increment / decrement ' Screen dimensions %MAXX = 639 %MAXY = 349 ' Init the random generator with a different value RANDOMIZE TIMER ' Sub: Switch Drawing / Displaying Screen SUB switchscreen STATIC drawing, display IF drawing = display THEN drawing = 0 display = 1 ELSE SWAP drawing, display END IF WAIT &H3DA, 8 ' wait for vertical retrace SCREEN 9, 0, drawing, display END SUB ' Sub: Draw rectangle SUB rectangle SHARED r() LINE ( r(0).x, r(0).y ) - ( r(1).x, r(1).y ), 11 LINE ( r(1).x, r(1).y ) - ( r(2).x, r(2).y ), 11 LINE ( r(2).x, r(2).y ) - ( r(3).x, r(3).y ), 11 LINE ( r(3).x, r(3).y ) - ( r(0).x, r(0).y ), 11 END SUB ' Sub: Calculate new points SUB newpoints SHARED r(), d() LOCAL i, bounds FOR i = 0 TO 3 bounds = boundcheck( r(i), d(i) ) SELECT CASE bounds CASE ( %UP OR %PORT ) r(i).x = 0 r(i).y = 0 d(i).x = -d(i).x d(i).y = -d(i).y CASE ( %UP OR %STARBORD ) r(i).x = %MAXX r(i).y = 0 d(i).x = -d(i).x d(i).y = -d(i).y CASE ( %DOWN OR %PORT ) r(i).x = 0 r(i).y = %MAXY d(i).x = -d(i).x d(i).y = -d(i).y CASE ( %DOWN OR %STARBORD ) r(i).x = %MAXX r(i).y = %MAXY d(i).x = -d(i).x d(i).y = -d(i).y CASE %UP r(i).x = ( -r(i).y * d(i).x ) / d(i).y + r(i).x r(i).y = 0 d(i).y = -d(i).y CASE %DOWN r(i).x = ( ( %maxy - r(i).y ) * d(i).x ) / d(i).y + r(i).x r(i).y = %MAXY d(i).y = -d(i).y CASE %PORT r(i).y = d(i).x / d(i).y * -r(i).x + r(i).y r(i).x = 0 d(i).x = -d(i).x CASE %STARBORD r(i).y = d(i).x / d(i).y * (%maxx - r(i).x) + r(i).y r(i).x = %MAXX d(i).x = -d(i).x CASE %NOPE INCR r(i).x, d(i).x INCR r(i).y, d(i).y END SELECT NEXT i END SUB ' Function boundcheck: ' Check if pixel left the frontiers of the screen FUNCTION boundcheck(pt AS pixel, dir AS pixel) AS INTEGER LOCAL work work = %NOPE SELECT CASE pt.y + dir.y CASE < 0 INCR work, %UP CASE > %MAXY INCR work, %DOWN END SELECT SELECT CASE pt.x + dir.x CASE < 0 INCR work, %PORT CASE > %MAXX INCR work, %STARBORD END SELECT boundcheck = work END FUNCTION ' Initializing the 2D object and the directions increments/decrements ' Just a few random numbers ... FOR i=0 TO 3 r(i).x = %MAXX * RND(1) r(i).y = %MAXY * RND(1) WHILE d(i).x = 0 d(i).x = 4 - 8 * RND(1) WEND WHILE d(i).y = 0 d(i).y = 4 - 8 * RND(1) WEND NEXT i ' Main Program ' Calling the SUBs and waiting for a key WHILE NOT INSTAT switchscreen ' Show screen CLS ' Clear the screen rectangle ' Drawing rectangle newpoints ' Calculate the new points WEND ************************************************************************** Listing II-3.1 If you change the main program to the one described in Listing II-3.2 then you will see why it's necessary to flip pages. The aninamtion of the rectangle will become flickery. So that's why page flipping is important for any type of animation. ************************************************************************** ' modified Main program ' actually it didn't flip the pages anymore ... SCREEN 9 WHILE NOT INSTAT CLS ' Clear the screen rectangle ' Drawing rectangle newpoints ' Calculate the new points WEND ************************************************************************** Listing II-3.2: RECTANGLE.BAS ------------------------------------------------- / / | -------------------------------------------------- | 3D Graphics in BASIC - Part II.4: 3D Object moving / -------------------------------------------------- Moving - or also called: translation - of an object is done by changing the coordinates of the object. Let's start with a simple example: a point in the 3D world. Moving the point could be done by: 1. changing the points coordinates: obj.x = obj.x + t.x obj.y = obj.y + t.y obj.z = obj.z + t.z With (obj.x/obj.y/obj.z) = 3D point and (t.x/t.y/t.z) = translation vector. The translation vector describes how much a point is moved in any direction (x,y,z). or (very important !) 2. changing the viewers coordinates: eye.x = eye.x + t.x eye.y = eye.y + t.y eye.z = eye.z + t.z With (eye.x/eye.y/eye.z) = viewers' point The result will be the same: The point will be moved. That's the same phenomon as if we watched the sunrise. Not the sun is going up but our planet earth is rotating around his polar axis. We know that the earth is moving but it looks like the sun is moving. The listing II-4.1 is the modified example of the last part - PYRAMID.BAS. Now it shows some motion. The pyramid is bouncing (in fact the viewpoint is moving) to the viewer and away from him/her. ************************************************************************** ' --------------------- ' Moving Pyramid ' based on PYRAMID.BAS ' (C) 1996 by Ch. Garms ' --------------------- ' Compiler Instructions $CPU 80386 $OPTIMIZE SPEED $LIB GRAPH ON $ERROR ALL ON $COMPILE MEMORY ' Creating new TYPEs TYPE vector x AS INTEGER y AS INTEGER z AS INTEGER END TYPE TYPE pixel x AS INTEGER y AS INTEGER END TYPE ' Variable declarations %MAXPT = 3 ' max. points %MAXLN = 5 ' max. lines DIM s(%MAXPT) AS pixel ' 2D coordinates of Pyramid DIM eye AS vector ' viewpoint DEFINT a-z ' Initializing screen constants %MAXPOSX = 639 ' max. X-coordinate of screen %MAXPOSY = 349 ' max. Y-coordinate of screen %CENTERX = 320 ' center of screen (X-position) %CENTERY = 175 ' center of screen (Y-position) ' Initializing Viewpoint eye.x = 15 eye.y = 15 eye.z = 0 ' Calculating the eye coordinates & transformation into screen pixels SUB vec2pix( objpt AS vector, scrpix AS pixel ) SHARED eye DECR objpt.x, eye.x DECR objpt.y, eye.y DECR objpt.z, eye.z scrpix.x = (objpt.x / objpt.z) * %MAXPOSX + %CENTERX scrpix.y = (objpt.y / objpt.z) * %MAXPOSY + %CENTERY END SUB ' Switch screens: ' implementation for PB's SCREEN SUB switchscreen STATIC display, drawing IF display = drawing THEN display = 0 drawing = 1 ELSE SWAP display, drawing END IF WAIT &H3DA, 8 ' wait for vertical retrace SCREEN 9, 0, display, drawing CLS END SUB ' IMPORTANT: from here starts the nonrecycable code ' Main program DIM pwork AS vector WHILE NOT INSTAT FOR j = 40 TO 200 STEP 2 switchscreen eye.z = j RESTORE objectdata FOR i = 0 TO %MAXPT READ pwork.x, pwork.y, pwork.z vec2pix pwork, s(i) NEXT i RESTORE connectdata FOR i = 0 TO %MAXLN READ pt1, pt2 LINE (s(pt1).x,s(pt1).y) - (s(pt2).x,s(pt2).y) NEXT i NEXT j FOR j = 200 TO 40 STEP -2 switchscreen eye.z = j RESTORE objectdata FOR i = 0 TO %MAXPT READ pwork.x, pwork.y, pwork.z vec2pix pwork, s(i) NEXT i RESTORE connectdata FOR i = 0 TO %MAXLN READ pt1, pt2 LINE (s(pt1).x,s(pt1).y) - (s(pt2).x,s(pt2).y) NEXT i NEXT j WEND SCREEN 0 ' Object Data & Connectivity list objectdata: DATA 30, 1, 1 DATA 1, 30, 1 DATA 1, 1, 30 DATA -30, -30, -30 connectdata: DATA 0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3 ************************************************************************** Listing II-4.1: MOVINPYR.BAS The listing II-4.1 has some nice features. It contains code that's recycable (you mustn't reinvent the wheel !). For our purposes there are two new SUBs: SUB switschscreen: This subroutine flips between two pages in the video mode 9 (640x375x16 colours). This EGA resolution is more than enough for simple vector graphics. SUB vec2pix: Converts a vector (3D point) to a screen pixel. This SUB is resolution independant. You have to define only the viewpoint (setting eye.x/eye.y/eye.z) and the screen parameters %MAXPOSX, %MAXPOSY,%CENTERX,%CENTERY before your first call. --------------------------------------------------- / / | ---------------------------------------------------- | 3D Graphics in BASIC - Part II.5: 3D Object rotating / ---------------------------------------------------- There isn't much to say about 3D rotating. Only formulas, formulas, formulas. I think our friend Formula Jones won't be unhappy if we come to the point right now: Rotating around the x-axis (Global coordinate system): x' = x*cos(alpha) - y*sin(alpha) y' = x*sin(alpha) + y*cos(alpha) z' = z Rotating around the y-axis (Global coordinate system): x' = x*cos(beta) + z*sin(beta) y' = y z' = -x*sin(beta) + z*cos(beta) Rotating around the z-axis (Global coordinate system): x' = x' y' = y*cos(gamma) - z*sin(gamma) z' = y*sin(gamma) + z*cos(gamma) With: (x/y/z) = old point (x'/y'/z') = new point alpha = angle to rotate around x-axis clockwise beta = angle to rotate around y-axis clockwise gamma = angle to rotate around z-axis clockwise I won't explain the origin of these formulas because that will not fit into this article. If you're interrested you'll find this very complex stuff in any "higher" math book. Listing II-5.1 is an example of use. Our well known pyramid is now rotating around his z- and x-axis. But the basic program can be easily changed. If you want to rotate to any other axis then you have only to change the calls. Just experimentate with this program ! ************************************************************************** ' --------------------- ' Rotating Pyramid ' based on PYRAMID.BAS ' (C) 1996 by Ch. Garms ' --------------------- ' Compiler Instructions $CPU 80386 $OPTIMIZE SPEED $LIB GRAPH ON $ERROR ALL OFF $FLOAT EMULATE ' Creating new TYPEs TYPE vector x AS INTEGER y AS INTEGER z AS INTEGER END TYPE TYPE pixel x AS INTEGER y AS INTEGER END TYPE ' Variable declarations %MAXPT = 3 ' max. points %MAXLN = 5 ' max. lines %FACTOR = 16384 %ANGLE = 3600 ' max. angles for sinus and cosinus DIM s(%MAXPT) AS pixel DIM sinus(%ANGLE) AS SHARED INTEGER ' array for sinus table DIM cosinus(%ANGLE) AS SHARED INTEGER ' array for cosinus table DIM eye AS SHARED vector ' viewpoint DIM pwork AS vector deg2rad! = 1800/3.14152695 DEFINT a-z ' Initializing Sinus table FOR i = 0 TO %ANGLE sinus(i) = CINT( SIN( i/deg2rad!) * %FACTOR ) cosinus(i) = CINT( COS( i/deg2rad!) * %FACTOR ) NEXT i ' Screen constants %MAXPOSX = 639 ' max. X-coordinate of screen %MAXPOSY = 349 ' max. Y-coordinate of screen %CENTERX = 320 ' center of screen (X-position) %CENTERY = 175 ' center of screen (Y-position) ' Clipping constants %LEFT = 1 %RIGHT = 2 %UP = 4 %DOWN = 8 %TRUE = -1 %FALSE = 0 ' Initializing Viewpoint eye.x = 0 eye.y = 0 eye.z = 150 ' Rotating Point around X-Axis ' objpt : vector in world coordinates (!) ' alpha : angle to rotate around X-Axis (1 means 0.1 deg) SUB rotatex( objpt AS vector, alpha AS INTEGER ) SHARED sinus(), cosinus() DIM p AS vector p.x = (objpt.x * cosinus(alpha) - objpt.y * sinus(alpha)) / %FACTOR p.y = (objpt.x * sinus(alpha) + objpt.y * cosinus(alpha)) / %FACTOR objpt.x = p.x objpt.y = p.y END SUB ' Rotating Point around Y-Axis ' objpt : vector in world coordinates (!) ' beta : angle to rotate around Y-Axis (1 means 0.1 deg) SUB rotatey( objpt AS vector, beta AS INTEGER ) SHARED sinus(), cosinus() DIM p AS vector p.x = (objpt.x * cosinus(beta) + objpt.z * sinus(beta)) / %FACTOR p.z = (objpt.x * -sinus(beta) + objpt.z * cosinus(beta)) / %FACTOR objpt.x = p.x objpt.z = p.z END SUB ' Rotating Point around Z-Axis ' objpt : vector in world coordinates (!) ' gamma : angle to rotate around Y-Axis (1 means 0.1 deg) SUB rotatez( objpt AS vector, gamma AS INTEGER ) SHARED sinus(), cosinus() DIM p AS vector p.y = (objpt.y * cosinus(gamma) - objpt.z * sinus(gamma)) / %FACTOR p.z = (objpt.y * sinus(gamma) + objpt.z * cosinus(gamma)) / %FACTOR objpt.y = p.y objpt.z = p.z END SUB ' Calculating the eye coordinates & transformation into screen pixels ' objpt : vector in world coordinates (!) ' scrpix: pixel on screen ' The variable eye (TYPE vector) must be defined before calling this sub. SUB vec2pix( objpt AS vector, scrpix AS pixel ) SHARED eye DECR objpt.x, eye.x DECR objpt.y, eye.y DECR objpt.z, eye.z scrpix.x = (objpt.x / objpt.z) * %MAXPOSX + %CENTERX scrpix.y = (objpt.y / objpt.z) * %MAXPOSY + %CENTERY END SUB ' Switch screens SUB switchscreen STATIC display, drawing IF display = drawing THEN display = 0 drawing = 1 ELSE SWAP display, drawing END IF WAIT &H3DA, 8 ' wait for vertical retrace SCREEN 9, 0, display, drawing CLS END SUB ' IMPORTANT: from here starts the nonrecycable code ' Main program WHILE NOT INSTAT FOR j=0 TO %ANGLE STEP 15 switchscreen RESTORE objectdata FOR i = 0 TO %MAXPT READ pwork.x, pwork.y, pwork.z rotatez pwork, j rotatey pwork, j vec2pix pwork, s(i) NEXT i RESTORE connectdata FOR i = 0 TO %MAXLN READ pt1, pt2 LINE (s(pt1).x,s(pt1).y) - (s(pt2).x,s(pt2).y) NEXT i NEXT j WEND SCREEN 0 ' Object Data & Connectivity list objectdata: DATA 30, 0, 0 DATA 0, 30, 0 DATA 0, 0, 30 DATA -30,-30, -30 connectdata: DATA 0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3 ************************************************************************** Listing II-5.1: ROTPYR.BAS The listing II-5.1 has a very nice trick: The sinus and cosinus values are converted to integers by multiplying with a constant factor (the factor must be less than 32767) and stored in an integer array. That makes the calculation of the 3D rotating faster than with floating point math. It is not a great secret because it is a well used technique for vector graphics since games like Elite on the C-64. Though the calculation aren't very precise the screen resolution is so small that calculation errors won't disturb much. The listing II-5.1 simplifies the rotating. As you can see all formulas rotate around an axis of the global coordinate system. But the pyramid is rotating around a point in the center of the pyramid. The program achieves this by equalising the center of the object and the center of the global coordinate system. If a chosen scenery is more complex (e.g. two objects who rotates differemt) then we come to a new coordinate system which I will now introduce: The Object coordinate system. That means: All points of a given object will be defined relative to the center of the object. To display the object in the global cordinate system (or: world coordinate system) we have only add the translation vector from the center of the object to the center of the global corrdinate system to all points of the object. For example I will take the single point once more for explanation of this complex subject: The point is the center of the object. The relative object coordinate will be (0/0/0) and the translation vector (x/y/z). To display the point into the world coordinate system we simply add the translation vector to the object coordinates so the derived global coordinte point is (x/y/z). In general: world.x = obj.x + transl.x world.y = obj.y + transl.y world.z = obj.z + transl.z with: (world.x/world.y/world.z) = world coordinates of object point (obj.x/obj.y/obj.z) = object coordinates of object point (transl.x/transl.y/transl.z) = translation vector of object That's the same as translating a 3D point in the world coordinate system. Now we've defined our object within the object coordinate system we only have to equalise the object center and the world center in our mind. For the rotations we take the object coordinates not the world coordinates ! Than we can perform the rotations. To display the object we add the translation vector of the object center to all object points and convert the points to screen pixels. ------------------------------------------------------------------- / / | --------------------------------------------------------------------- | 3D Graphics in BASIC - Part II.6: Introductions to Matrix calculations / ---------------------------------------------------------------------- Matrix operations aren't a mystical thing. You have not to be a math genius to understand what matrices are: "A Matrix is a represantion of a linear equation" In other words: A Matrix isn't more than an array of values which contains the suffixes of any linear equation like: a1*x + b1*y + c1*z = d1 a2*x + b2*y + c2*z = d2 a3*x + b3*y + c3*z = d3 The corresponding matrix looks as follows: |a1 b1 c1| |d1| |a2 b2 c2| = |d2| |a3 b3 c3| |d3| For our purposes we didn't need more to know. As you have seen our 3D operations are often performed by linear equations. E.g. translation of a point is performed by adding the translation vector to a point. If we write down this equation in a matrix form it will look like: Matrix1 Matrix2 Matrix3 |x| |1 0 0 t.x| |x + t.x| |y| |0 1 0 t.y| = |y + t.y| |z| |0 0 1 t.z| |z + t.z| |0| |0 0 0 0 | |0 | That means we only multiply the 3D point (Matrix1) with an operator (Matrix2) to translate the point. It looks like I want to complicate all. But the advantage of matrix operations is that you can chain many 3D operations like rotation or translation to only one single matrix for all points of any object. This will reduce the calculations enormous and speed up 3D graphics dramatically for larger objects. OK, guys. Next time I will continue you to explain the calculation with matrix and go further with filled polygon graphics. Hope to see you again here. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [2.1] - Letters Ý Written by Various +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Letters have been pouring in for a while now and now it has been decided to publish a few: > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >I've been given your name as the editor of Basic fanzine. The problem I >have is that we use Qbasic to teach students about I/O on the PC - to >achieve a 1mSec delay we can use a decrementing loop. However, this method >is not transportable between machines with different clock speeds. >So what I'm looking for is a QBasic routine that allows me to set delays at >1mSec level (the Timer only allows ~50mSec). >can you advise me as to where I can find this info ? This advice may seem useless to you but this sort of precision IO cannot really be implemented well in QBasic. QBasic is an interpreter and takes far longer than 1ms to execute one statement. C (although it is a rather horrid language) is much more suited to this, or ASM (my personal preference). I do have some information about how to program the PC PIT clock chip to send out interrupts at specified intervals (1ms in your case), you may find it of use. I do not know how to implement ASM into QBasic properly but there is someone on the newsgroup who is an absolute master at this, if you cannot get the follow article to work properly then post a message to newsgroup: comp.lang.basic.misc ----------- >Dear Sir, >I have checked out your page about the Basic Magazine. It is absolutely >full of good information and excellent programming techniques. >Is it possible to make a subscription form in order to be able to receive >the contents of the magazine by e-mail ? >Well, if not it is still great. Hi Nicholas, Thank you for the praise! =) I am afraid there is no such facility at the moment although Fanzine Interactive will hopefully be in place soon. A facility to enable you to use a form to be a member of the mailing list is a good idea and I will try to implement it. There is of course a mailing list for the fanzine maintained by Tony Relyea of Russian-Under Ware. Read details in Section [[[[[[[]]]]]]]]]]]] ----------- > >Hello, I'm french and i want to know if gfa basic windows exist for pc? I have only ever seen GFA Basic for the PC. There is a GFABASIC for Windows also. Contact the manufacturer. If there is no hope then try the gfa-basic newsgroup alt.lang.gfa-basic +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [2.2] - References (The Pit Stop in BASIC) Ý Written by Fanzine Internal +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Welcome to References, the one place where you find the greatest BASIC sites whether they be link sites or sites full of info and code :) ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ -) Basix BASIC Fanzine on Web http://www.trenham.demon.co.uk/fanzine/ -) PowerBASIC http://www.powerbasic.com/ Providing Quality Products -) qbasic.com http://www.qbasic.com/ Lots of Source code available for download + more! -) QBASIC Three Dee Engines :) http://www.trenham.demon.co.uk/threed/ -) The Official BASIC Ring http://www.professionals.com/~peterp/ -) ABC [United States] http://charlie.simplenet.com/abc/abchome.html [European] http://pitel-lnx.ibk.fnt.hvu.nl/~excel/pbabc.html -) PowerBasic Archives http://pitel-lnx.ibk.fnt.hvu.nl/~excel/pb.html +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [2.3] - NEWS! (Read all about it) Ý Written by Fanzine Internal +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ =FAQ?=---- [The new fully reconditioned BASIC FAQ will be hitting the newsgroups near] [you soon! The project, run and led by Rick Elbers, has been progressing ] [well and a full BASIC FAQ is nearly ready.It covers most topics you would] [expect to find in an FAQ plus a few more!] This news article was written before recent events which seem to have given the FAQ an uncertain future. More news as we get it. =PowerBASIC News=---- PowerBASIC has stepped up a few pegs investing in an on-site webboard for users and people interested in PowerBASIC. You can post your questions, complaints and ideas there. The board is available under: http://www.powerbasic.com/ Go join in the discussion. =More PowerBASIC News!=---- PowerBASIC also has its own newsgroup, the creator of the group Peter Cooper said: ' PowerBASIC is an extremely popular company and I feel that they need a newsgroup of their own. The Webboard is a great idea but nothing can beat the way of USENET ' The newsgroup is available as alt.lang.powerbasic . If this newsgroup is not available on your server then it would be appreciated if you could bug the news-admin to add it as to spread the group worldwide. =New ABC Packet=---- William Yu has released another quality ABC packet for all of you source leeches to drool over. The packet (dated January '97) is available at the ABC sites. =Fanzine Pages Being Reconditioned=---- The Fanzine Pages are now undergoing heavy reconstruction and conditioning. We are hoping to have 'Fanzine Interactive' online soon plus copies of all the zines in HTML format. For the current time all issues of the fanzines are available to download but there are no extended features. News will be posted when the site is nearing perfection! =Ben Ashley Stumbles Back to Newsgroup=---- Ben Ashley (http://www.flag.demon.co.uk) aka Moo-Juice, comes back to comp.lang.basic.misc. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [3.1] - Copy Routine Ý Written by Moritz Mhlenhoff +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ' This is a copy-routine I wrote for one of my install-progs ' It features a status bar and shows the finished percentage. ' I think the code is easy to understand. DIM piece AS INTEGER ' piece is the amount of bytes copied in a rush ' the bigger the piece, the faster the copying of ' big files. piece can be 0-32000 bytes DIM length AS LONG ' lenght is the amount of bytes still to copy CLS INPUT "Enter the name of file to copy : "; d1$ INPUT "Enter the target path + file name: "; d2$ OPEN d1$ FOR BINARY AS #1 OPEN d2$ FOR OUTPUT AS #2 lenght = LOF(1) totallenght = LOF(1) piece = 10000 CLS LOCATE 3, 4: PRINT "Percent finished:" LOCATE 4, 4: PRINT STRING$(50, 177) rest = lenght DO IF piece > lenght THEN piece = lenght t$ = INPUT$(piece, #1) PRINT #2, t$; kop = kop + piece pro = CINT(kop / totallenght * 100) LOCATE 3, 35: PRINT pro; "%" LOCATE 4, 4: PRINT STRING$((pro / 2), 178) lenght = lenght - piece LOOP UNTIL lenght < 1 Thanks for that code Moritz! :) Length.. :) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [3.2] - 18Bit GFX in PB Ý Written by Daniel Garlans +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ This program was written by Daniel Garlans (garlans@mindspring.com) and packaged together with the PAL routine by Peter Cooper. 'Fake Color Mode - 320x400 256 color emulating...320x133 18bit mode :) 'defint a-z print "Preparing FakeMode" mode18bit cls18bit for a=0 to 365 for b=0 to 590 pset18 a,b,63,63,63 next b next a !mov ah,&H03 !int &H10 sub pset18(x,y,r,g,b) ';efint a-z 'Fake-18bit modeX routine... dim page as integer dim pagebit as integer page = X and 3 'Find the modex Plane to write to pagebit=1 shift left pagebit, page 'a whole heck of a lot faster than 2^page :) poke &H3C4, 2 'Tell the vidcard which register:index I'm gonna mess with poke &H3C5, pagebit 'Tell the vidcard which page I want to write to def seg=&HA000 'go into the vidcard memory incr y,3 offsetr&=(100)*y + (x / 4) 'Get the offset for the RED portion '(for the fakerez) offsetg&=(100)*(y+1) + (x / 4) 'Get the offset for the GREEN portion offsetb&=(100)*(y+2) + (x / 4) 'Get the offset for the BLUE portion poke offsetr&,r poke offsetg&,g+64 poke offsetb&,b+128 end sub sub mode18bit !mov ax,&H0013 !int &H10 OUT &H3D4, &H11 : OUT &H3D5,INP(&H3D5) AND &H7F OUT &H3C2, &HE7 OUT &H3D4, &H0: OUT &H3D5, &H6C OUT &H3D4, &H1: OUT &H3D5, &H63 OUT &H3D4, &H2: OUT &H3D5, &H6D OUT &H3D4, &H3: OUT &H3D5, &H0 OUT &H3D4, &H4: OUT &H3D5, &H64 OUT &H3D4, &H5: OUT &H3D5, &H0 OUT &H3D4, &H6: OUT &H3D5, &H6C OUT &H3D4, &H7: OUT &H3D5, &HF0 OUT &H3D4, &H8: OUT &H3D5, &H0 OUT &H3D4, &H9: OUT &H3D5, &H60 OUT &H3D4, &H10: OUT &H3D5, &H5B OUT &H3D4, &H11: OUT &H3D5, &H8C OUT &H3D4, &H12: OUT &H3D5, &H57 OUT &H3D4, &H13: OUT &H3D5, &H32 OUT &H3D4, &H14: OUT &H3D5, &H0 OUT &H3D4, &H15: OUT &H3D5, &H58 OUT &H3D4, &H16: OUT &H3D5, &H65 OUT &H3D4, &H17: OUT &H3D5, &HE3 OUT &H3C4, &H1: OUT &H3C5, &H1 OUT &H3C4, &H4: OUT &H3C5, &H6 OUT &H3CE, &H5: OUT &H3CF, &H40 OUT &H3CE, &H6: OUT &H3CF, &H5 OUT &H3CE, &H6: OUT &H3CF, &H5 for a=0 to 63 setpal a, a, 0 ,0 'set up the pallete setpal a+64, 0, a, 0 setpal a+128, 0, 0, a next a end sub sub cls18bit def seg=&HA000 for a=0 to 64000 poke a,0 next a end sub SUB SetPal(BYVAL Col AS BYTE,BYVAL R AS BYTE,BYVAL G AS BYTE,BYVAL B AS BYTE) !mov dx,&H3c8 !mov al,col !out dx,al !inc dx !mov al,r !out dx,al !mov al,g !out dx,al !mov al,b !out dx,al END SUB +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [3.3] - Font Placement Ý Written by Byron Smith and Peter Cooper +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ About 6 months ago Peter released some very basic code for reading fonts from the font ram for placement onto the screen. Byron Smith (unol@sat.net) took this many steps further and optimised the code greatly. Here is that code, there may be some problems with word wrapping if you are viewing this on the newsgroup.. DECLARE SUB fontput (z1%, y1%, in$, c%) DECLARE SUB fontput1 (z1%, y1%, in$, c%) DECLARE SUB fontput2 (z1%, y1%, in$, c%) RANDOMIZE TIMER SCREEN 12 CLS PAINT (1, 1), 1 fontput 0, 0, "The old algorithm...", 2 fontput 258, 8, "FontPut Demo", 0 fontput 260, 10, "FontPut Demo", 15 fontput 20, 30, "I dont expect you to use this procedure but it uses a technique unknown", 15 fontput 20, 50, "to many programmers. It reads direct from the font area in ROM, instead", 15 fontput 25, 70, "of using the method used by many programmers in which they PRINT their", 15 fontput 30, 90, "text and then use the POINT command... so you can use this method in", 15 fontput 20, 110, "place of that old method, look at the fontput procedure.. Cheers {:o)", 15 fontput 20, 150, "Peter Cooper", 14 A$ = INPUT$(1) CLS fontput 1, 1, "PRESS ANY KEY TO EXIT!", 12 A$ = INKEY$ DO x% = INT((550 - 0 + 1) * RND + 0) y% = INT((470 - 1 + 1) * RND + 1) c% = INT((15 - 1 + 1) * RND + 1) fontput x%, y%, "Hello there!", c% LOOP UNTIL INKEY$ <> "" SCREEN 13 CLS FOR c% = 30 TO 16 STEP -1 fontput 130, 80, "Cheers!", c% FOR d% = 1 TO 1000 FOR d2% = 1 TO 40 NEXT d2% NEXT d% WAIT &H3DA, 8 WAIT &H3DA, 8, 8 NEXT c% LOCATE 25, 1: PRINT "Press any key to continue"; WHILE LEN(INKEY$) = 0: WEND SCREEN 12 CLS PAINT (1, 1), 1 fontput2 0, 0, "The ", 2 fontput2 32, 0, "NEW ", 10 fontput2 64, 0, "algorithm...", 2 fontput2 258, 8, "FontPut Demo", 0 fontput2 260, 10, "FontPut Demo", 15 fontput2 20, 30, "I dont expect you to use this procedure but it uses a technique unknown", 15 fontput2 20, 50, "to many programmers. It reads direct from the font area in ROM, instead", 15 fontput2 25, 70, "of using the method used by many programmers in which they PRINT their", 15 fontput2 30, 90, "text and then use the POINT command... so you can use this method in", 15 fontput2 20, 110, "place of that old method, look at the fontput procedure.. Cheers {:o)", 15 fontput2 20, 150, "Peter Cooper", 14 A$ = INPUT$(1) CLS fontput2 1, 1, "PRESS ANY KEY TO EXIT!", 12 A$ = INKEY$ DO x% = INT((550 - 0 + 1) * RND + 0) y% = INT((470 - 1 + 1) * RND + 1) c% = INT((15 - 1 + 1) * RND + 1) fontput2 x%, y%, "Hello there!", c% LOOP UNTIL INKEY$ <> "" SCREEN 13 CLS FOR c% = 30 TO 16 STEP -1 fontput2 130, 80, "Cheers!", c% FOR d% = 1 TO 1000 FOR d2% = 1 TO 40 NEXT d2% NEXT d% WAIT &H3DA, 8 WAIT &H3DA, 8, 8 NEXT c% SUB fontput (z1%, y1%, in$, c%) DEF SEG = &HFFA6 o1% = z1% FOR l% = 1 TO LEN(in$) l$ = MID$(in$, l%, 1) FOR y% = y1% TO y1% + 7 x% = PEEK(&HE + (ASC(l$) * 8) + (y% - y1%)) FOR z% = 0 TO 7 IF x% AND (2 ^ (7 - z%)) THEN PSET (z1%, y%), c% z1% = z1% + 1 NEXT z% z1% = z1% - 8 NEXT y% z1% = z1% + 8 NEXT l% DEF SEG END SUB 'Author: Byron Smith , 13-NOV-1996 SUB fontput1 (z1%, y1%, in$, c%) DEF SEG = -90 FOR b% = 1 TO LEN(in$): FOR m% = 0 TO 7 d% = 128 * PEEK(14 + 8 * ASC(MID$(in$, b%, 1)) + m%) LINE (z1% + 8 * b% - 9, y1% + m%)-(z1% + 8 * b% - 2, y1% + m%), c%, , d% NEXT m%, b% END SUB 'Author: Byron Smith , 25-JAN-1997 'Update: Draws two characters at once using LINE. SUB fontput2 (z1%, y1%, in$, c%) DEF SEG = -90 tmp$ = in$ + " " FOR b% = 1 TO LEN(tmp$) - 1 STEP 2: FOR m% = 0 TO 7 d& = 256& * PEEK(14 + 8 * ASC(MID$(tmp$, b%, 1)) + m%) 'join the next line + PEEK(14 + 8 * ASC(MID$(tmp$, b% + 1, 1)) + m%) d% = d& + (d& > 32767) * 65536 LINE (z1% + 8 * b% - 8, y1% + m%)-(z1% + 8 * b% + 7, y1% + m%), c%, , d% NEXT m%, b% END SUB +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [4.1] - LikED Review Ý Written by Daniel Garlans (White Shade\DuoTech) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Liked is a powerful editor written by Leif Claesson (Liket/Goto10 or TPCF), a Swede who happens to program demos in PowerBasic. He apparently didn't like the Powerbasic editor, (which I agree with), so he wrote LikED in PB3. Liked's interface is pretty straightforward, you start with a blank screen where you start typing your code. HelpPC is supported, (HelpPC is a very good index-reference program with all sorts of Interrupt, ASM help, and almost anything you could ask about in the PC). A menu screen gives you all the options, just like PowerBasic's editor does. Compiling uses the same keys as the regular editor, and requires that you have the PBC.EXE compiler in a directory for Liked to use. Most "common" editing commands are supported as well. Besides the basics, liked also supports an almost scripting-like set of commands. It has options to run before and after compiling, automatic appending, size showing and more. There is no mouse support, but Liked doesn't really need it. Also, support for TASM linking is included. So, Basically, if you're tired of the regular PowerBasic 3.2 editor, try Liked... You can get liked at: http://home1.swipnet.se/~w-18147/liket.htm btw, the author does not know that this exists :) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [4.2] - Site of the Issue! Ý Written by Peter Cooper +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Welcome to the new series, site of the issue where we strive to find the best QBasic site around. Of course this will change each week for variety but we hope to find you the best BASIC content around! This issue qbasic.com is the clear winner. Qbasic.Com ~~~~~~~~~~ Qbasic.com is a well laid out, well managed site from Avatar. There is an awful lot of code to be downloaded, from Palette tricks to 3d engines to games. Theer are some good games for download too, for example, BattleCraft which is a Warcraft style sim in QBasic! It seems Avatar has put a lot of work into the site, buying the domain etc and the site receives a great deal of hits per day. It's a booming success! From the site you can also order a CD which contains all of the code on the site and also 'much more!'. Compilers can also be downloaded from the site which gives 'wanna-be' programmers a giant head start. Tutorials are also available for beginners but even some of the more advanced programmers can learn a lot! This is a definately must-visit site. You might not think the pages are gleaming with HTML technology, but it's 'content'. Leap in, and have a go! +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [5.1] - Contact Ý Written by Fanzine Internal +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ The Basix Fanzine is always ready for new articles, code, letters and so on. We are always appreciative of anything you send which could be of use, come and try! Send your contributions to: fanzine@trenham.demon.co.uk Many thanks... Also! Remember the Basix Fanzine does have a mailing list.. To join the mailing list : arelyea@vt.edu with the following line in the subject header: subscribe basix-fanzine Any text in the body of the message will be ignored. The mailing list is run by Mr. Relyea and the Basix Fanzine claims no responsibility for any problems with the mailing list. Tom Lawrences HTML Fanzine is of his responsibility and again the Basix Fanzine claims no responsibility for any problems. +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ [5.2] - And in the end... Ý Written by Peter Cooper +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 'And in the end.. the love you take is equal to the love you make' - The Beatles Interesting words from John Lennon there, perhaps it could be twisted to a programmers point of view.. 'And at the end.. the code you break is equal to the code you make!' Maybe not. It's been an interesting issue. As you may have noticed the format has changed a bit and there are some new fresh articles. This fanzine also seems to be nearly on time! Not much to say for the end, it's now much warmer out than from this time last fanzine and the BASIC scene has changed a bit.. My personal recommendation (as you already know) this issue goes to: http://www.qbasic.com/ The site is quite good, the style may not be to everyones taste but there is definately some good content. You will find a lot to use there. Although my raycasting program does seem to have someone else down as author.. Read the review of the site in section 4.2: Remember, keep coding, and send in what you would like in the fanzine, even ads for your homepages! We need your input! 9th February 1997