============================================================================== QBASIC BSAVE FILES BY TEK ------------------------------------------------------------------------------ Author: Jason Jones (Tek, tek@quickbasic.com) Created: 01/27/99 Last Revision: 01/27/99 Version: 1.00 My site is at http://neozones.quickbasic.com, and I can be reached via email with the address tek@quickbasic.com. My ICQ number is 825301. What are BSAVE files? You've probably seen them around in many people's projects (qbasic), and perhaps you know what they are, or are good for. BSAVE files have a broad spectrum of uses. In it's simplest definition, BSAVEing will copy a chunk of memory (specified) to a file. A fairly common use of BSAVE is to save the screen in 13h (SCREEN 13). An example of this is: SCREEN 13 FOR i% = 1 TO 200 PSET (RND * 320, RND * 200), RND * 256 NEXT i% DEF SEG = &HA000 BSAVE "screen.bsv" DEF SEG This code snippet will take the screen with 200 random pixels, save it to a file, and can be loaded later if such is desired. The important parts of this code are the DEF SEG and the BSAVE. DEF SEG is very important to bsaveing also. When you use bsave to make a file out of memory, you need to tell bsave what the current memory SEGMENT is. For those of you who don't know, &HA000 is a way of representing the SCREEN 13 memory segment in qbasic. The last, blank DEF SEG, will return the current memory segment to it's previous position. So that's all good, but, how do we load the screen back up? Glad you asked... SCREEN 13 DEF SEG = &HA000 BLOAD "screen.bsv" DEF SEG That's all there is to it! You are well on your way to understanding BSAVE and BLOAD. Now, what about making/loading individual image files? First, a quick review of QBasic's GET and PUT commands (for graphics). QBasic can store bitmap screen graphics in arrays, which can then be drawn using PUT, which is quite a bit faster than setting each and every pixel on the screen every time. An example of allocating memory, drawing, getting/ storing, and showing, now follows: Let's say that we want to store a 20x20 image. To calculate the needed memory we can use this algoritm: Bytes% = ImageWidth * Image Height + 4. We need 4 extra bytes for the width/height of the image. So 20 * 20 + 4 = 400 + 4 = 404. We need 404 bytes. An integer is 2 bytes, so that means we need 202 integers. Assuming the array starts at 0, we can dim the image like so: DIM SHARED Image%(201) ' 404 bytes for image (202 integers) SCREEN 13 ' Set the screen LINE (100, 100)-(119, 119), 15, B '\ LINE (100, 100)-(119, 119), 4 '|-- Draw a box/x LINE (100, 119)-(119, 100), 1 '/ GET (100, 100)-(119, 119), Image% ' Get a 20x20 chunk, and put it in array Image%. PUT (0, 0), Image%, PSET ' Show image at coords. PUT (200, 60), Image%, PSET ' Show image at coords. Okay, we made space for an image in memory, we drew a misc. image, and we used the GET command to put the rectangular section into the array. As a side bonus we showed the image on the screen to illustrate this process. Now, you want to store the image in a FILE. Well, using handy-dandy BSAVE we can do this rather painlessly and simply. Continuing on the last section of code: DEF SEG = VARSEG(Image%(0)) ' Memory SEGMENT on Image% BSAVE "newtile.mdt", VARPTR(Image%(0)), 404 There, it's that simple. What's that? Your lost? Sorry. Here's what all the 'new' commands are for. Let's break down the BSAVE syntax. BSAVE [filename], [memory offset], [bytes] Of course, the filename is going to be "newtile.mdt". But what's the memory offset? The memory offset is the element at which the image starts. You see, an array could have been twice as big, and one array could hold multiple images, so you need to tell QBasic which of these images you want. In this simple example, we had everything at 0. Note that the following lines of code are the same: GET (100, 100)-(119, 119), Image% GET (100, 100)-(119, 119), Image%(0) Now, the last part, the number of bytes to write. Going back to the DIM section, we know we have 202 integers, so that's 202 * 2, which will give us 404 bytes. What filesize do you see on the file? It's 411 bytes! Oh no, what went wrong? Nothing went wrong, if the file "newtile.mdt" was 411 bytes. The 'extra' 7 bytes that seemed to come out of nowhere are actually a header at the beginning of each QBasic/QuickBasic BSAVE file. For all intents and purposes, you might as well just ignore them. Okay, so now we want to load an image with bsave. Also simple. Assuming that you know the dimensions of the image being loaded (like a normal 20x20 tile found in many RPG's), we can make an array to store the image. DIM SHARED Image%(201) And now we set the current memory segment to that array. DEF SEG = VARSEG(Image%(0)) And now to bload. BLOAD "image.mdt", VARPTR(Image%(0)) This concludes BSAVES 101, I hope to have a more advanced tutorial on BSAVES out later, covering multiple images in an array, more info on offsets, how to store multiple images in a file, and how to manually load/save BSAVE files using QBasic's GET/PUT commands for files.