phoney Posted December 18, 2023 Share Posted December 18, 2023 Okay, here's another question. (For FastBasic.) I have taken some graphics from my PC and turned them into binary bitmaps I am trying to reproduce on the Atari. So right now I have something like (start a location X, Y) DATA 0,1,1,0,0,0,1,1,1,1,1,1,0,255 (read from the data) (if value is 1, PLOT a point, in any case increment X, if it's 255 increment Y ... eventually the value could be from 0 to 3 based on color) It works, but this seems very inefficient as the DATA statements become very long to cover every pixel of a 160-pixel wide screen. I understand I can encode 8 pixels in a byte, but I don't understand how to decode them so I can use the PLOT command with them. Like, if I turn 01110010 into 114, how do I turn it back into 01110010 (I guess as an eight digit array) so I can tell where to PLOT? Or can I somehow figure out how to PLOT eight pixels in a row using that number 114. But also how would I then encode the color data ... I see a lot of people using what appear to be bitmapped objects encoded as a few bytes, but I can't figure out how to get from 'there' to 'here' in terms of plotting the object on the screen, especially with color data. I feel like this has been covered in articles but I can't quite figure out how to turn my question into what they are answering. They all seem to assume I've memorized a lot of things about the memory map and honestly I want to use PLOT because every time I try to address screen locations with POKE I get them slightly wrong, and speed doesn't matter. Also FastBasic doesn't seem to be able to address anything higher than 32767 as a variable??? Which makes it hard to address a lot of screen locations. Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 18, 2023 Share Posted December 18, 2023 If it's a significant amount of graphics, like over a few hundred bytes then you're probably better off keeping them in a file. Using PLOT is also pretty slow, adding decoding packed graphics could see it take an hour to load a single screen. An entire screen dumped as a 4 or 8K file would take a while to load using GET/POKE (like over a minute) but still be way quicker than PLOT. Quote Link to comment Share on other sites More sharing options...
phoney Posted December 18, 2023 Author Share Posted December 18, 2023 So, like, put all the data to a file as a string of 0s and 1s, (or 0-1-2-3s) and GET that data byte by byte? I feel like all the I/O would make it even slower compared to keeping it in the program, no? I'm 'printing' a 160x8 header and four 32x32 objects (from a library of about 16). The objects change. Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 18, 2023 Share Posted December 18, 2023 No - for a file I mean having the data as it's raw, native value. Atari bitmap like many old computer uses packed (chunky) pixels. So a byte might have bits set like: 0 0 0 1 1 0 1 1 Example there would be 4 pixels with colours 0, 1, 2, 3. Storing the raw data is the most efficient way aside from compression (ignoring procedural generation techniques) Quote Link to comment Share on other sites More sharing options...
phoney Posted December 18, 2023 Author Share Posted December 18, 2023 So, what I don't understand is how to take a byte like that and, in FastBasic, extract the bits so I can plot them in the right colors. That number you gave me (four pixels) is 27. But I don't know what to do with that 27. I know I can read a bunch of 0s and 1s from a DATA, COLOR Z and PLOT X,Y. But I don't know how to get the "27" there into a form I can use and how to use it. Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted December 18, 2023 Share Posted December 18, 2023 It's poked directly into the screen memory. Quote Link to comment Share on other sites More sharing options...
phoney Posted December 18, 2023 Author Share Posted December 18, 2023 Is there any way to do that without poking it directly into the screen memory? Because whenever I try that the location is wrong. I think it may have something to do with FastBasic being unable to assign numbers to variables that are greater than 32768. Quote Link to comment Share on other sites More sharing options...
robus Posted December 18, 2023 Share Posted December 18, 2023 What is your display list currently? I'm assuming it's set to a Graphics mode? If so then it has a pointer to memory that is ready for data to be interpreted as pixels. Just load your data into that area of RAM and it will be displayed. The bits that are set will choose which color register to display (depending on the graphics mode). Quote Link to comment Share on other sites More sharing options...
phoney Posted December 18, 2023 Author Share Posted December 18, 2023 Graphics 7, Atari 800. Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted December 18, 2023 Share Posted December 18, 2023 4 hours ago, phoney said: Because whenever I try that the location is wrong. The screen memory is PEEK(88)+PEEK(89)*256 (sorry, don't use FB, so don't know if it does a DPEEK) each line in GR.7 is 40 bytes, so to calculate a pixel you need to PEEK the location, mask out the pixel you want to insert, then OR in your new pixel with the colour you want. So for a given X,Y coordinate, you multiply the Y by 40 then add the X/4 to get the screen byte. pixels are as follows in a byte, bits 7&8 are pixel 0 6&5 are pixel 1 4&3 pixel 2 and 1&0 are pixel 3, this is for all bytes. Quote Link to comment Share on other sites More sharing options...
phoney Posted December 19, 2023 Author Share Posted December 19, 2023 Okay, so why isn't this working? It's a picture of a T-Shirt divided into 32 lines of 8 bytes each. I read eight bytes, write them to the screen, jump down 40 bytes and repeat ... but the lines are not ending up on top of each other. Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 19, 2023 Share Posted December 19, 2023 You increment LOC each time then add 40 to it before the end of the outer loop. You should only add 32 since it's already had 8 added to it in the inner loop. Quote Link to comment Share on other sites More sharing options...
phoney Posted December 19, 2023 Author Share Posted December 19, 2023 Oh! Thank you! Now it works! Quote Link to comment Share on other sites More sharing options...
phoney Posted December 19, 2023 Author Share Posted December 19, 2023 Now if I have like 16 of these objects, and they're 1K each, can I even encode them in my program, or do I need to write a bunch of 1K files to disk and read them in as needed? I also have a weird Axlon board in my computer but the idea of bankswitching memory is making my head explode. Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted December 19, 2023 Share Posted December 19, 2023 I don't think you can use bank switching in Fast Basic, the memory window is at $4000 to $7FFF, so highly likely your BASIC code will live in this area. Quote Link to comment Share on other sites More sharing options...
phoney Posted December 19, 2023 Author Share Posted December 19, 2023 OK. So, do you think I should be putting a bunch of long DATA statements in here, or creating some 1K files on the disk and reading them byte by byte when I need the graphic? Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted December 19, 2023 Share Posted December 19, 2023 the latter (or preload them and copy when needed if you have the space) Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted December 19, 2023 Share Posted December 19, 2023 1 hour ago, phoney said: OK. So, do you think I should be putting a bunch of long DATA statements in here, or creating some 1K files on the disk and reading them byte by byte when I need the graphic? You could always store your data in strings, again if you have the space, that way each character only uses 1 byte where as each DATA statement uses 6 bytes for the first element and a further 3 or 4 bytes for each extra item on the line. I've used that method in a fruit machine game I wrote that needed a custom character set and stored the new set in several strings and extracted the data from the strings at run time. Quote Link to comment Share on other sites More sharing options...
dmsc Posted December 20, 2023 Share Posted December 20, 2023 (edited) Hi! 10 hours ago, phoney said: OK. So, do you think I should be putting a bunch of long DATA statements in here, or creating some 1K files on the disk and reading them byte by byte when I need the graphic? There are advantages and disadvantages to each option: - If you put the data inside your program, you can generate a single binary file that will load and run, this is easier to program and easier to distribute. - If you put the data as files in a disk, you can have a lot more data, as only the objects that you need would be in RAM. This will allow for more content/levels/objects, but not all at the same time. This is an example of fast drawing your image using inline DATA and MOVE (much faster than copying individual bytes): ' Image Drawing Example ' --------------------- ' Image Data, 32 * 28 pixels, 4 pixels per byte, 224 bytes total: DATA Image() Byte = 0,0,23,255,255,245,0,0,0,1,109,85,85,94,80,0, DATA Byte = 0,26,171,85,85,122,164,0,0,106,170,213,85,234,169,0, DATA Byte = 0,170,175,255,255,250,170,0,1,170,191,255,255,254,170,64, DATA Byte = 2,170,255,255,255,255,170,128,6,171,255,255,255,255,234,144, DATA Byte = 6,167,255,255,255,255,218,144,10,171,255,255,255,255,234,160, DATA Byte = 26,167,255,255,255,255,218,164,26,167,255,255,255,255,218,164, DATA Byte = 26,167,255,255,255,255,218,164,21,87,255,255,255,255,213,84, DATA Byte = 0,7,255,255,255,255,208,0,0,7,255,255,255,255,208,0, DATA Byte = 0,7,255,255,255,255,208,0,0,7,255,255,255,255,208,0, DATA Byte = 0,7,255,255,255,255,208,0,0,7,255,255,255,255,208,0, DATA Byte = 0,7,255,255,255,255,208,0,0,7,255,255,255,255,208,0, DATA Byte = 0,7,255,255,255,255,208,0,0,7,255,255,255,255,208,0, DATA Byte = 0,7,255,255,255,255,208,0,0,7,255,255,255,255,208,0, DATA Byte = 0,7,255,255,255,255,208,0,0,5,85,85,85,85,80,0 ' Set Graphics mode 7+16 (160x96) GR. 7+16 ' Loop forever: DO ' Generate a new random position: PosX = RAND(160-32) PosY = RAND(80-28) ' Draw the image @Draw PosX, PosY ' Wait half a second PAUSE 30 ' Erase the image @Erase PosX, PosY LOOP ' Draws the image at X,Y coordinates: PROC Draw Draw_X Draw_Y Draw_Src = &Image Draw_Dst = DPeek(88) + Draw_Y * 40 + Draw_X / 4 FOR I=0 TO 27 MOVE Draw_Src, Draw_Dst, 8 Draw_Src = Draw_Src + 8 Draw_Dst = Draw_Dst + 40 NEXT ENDPROC ' Erase the region at X,Y coordinates: PROC Erase Draw_X Draw_Y Draw_Dst = DPeek(88) + Draw_Y * 40 + Draw_X / 4 FOR I=0 TO 27 MSET Draw_Dst, 8, 0 Draw_Dst = Draw_Dst + 40 NEXT ENDPROC 9 hours ago, TGB1718 said: You could always store your data in strings, again if you have the space, that way each character only uses 1 byte where as each DATA statement uses 6 bytes for the first element and a further 3 or 4 bytes for each extra item on the line. On FastBasic, DATA statements don't use space for the text representation, only for each actual byte of data - this means that they will use less memory than a string. And if using the cross-compiler, the DATA can be included from a file instead of typed into the program. Have Fun! sample.xex sample.fb Edited December 20, 2023 by dmsc Attach program. 2 Quote Link to comment Share on other sites More sharing options...
bfollett Posted December 20, 2023 Share Posted December 20, 2023 It's been a long time, but I used machine language routine that hooked into the DOS file input/output routines and loaded or saved from disk to/from computer memory at full disk access speed. The routine was only 39 bytes long and I stored it in a string variable called IO$. I used it in my program "Space Station Multiplication" featured in Antic magazine. It loaded an 8kb picture and some animation frames into memory. I had a second routine that moved the animation frames from high memory into the visible screen area. Those routines sound like they might be just what you're looking for. As to Fast Basic only supporting integers with values between -32768 to 32767, you do have a full 64k of values, just half of them are negative, internally one bit of the number is just used to interpret the number as positive or negative, so you should be able to just use negative numbers to represent the high values above 32k through 64k, they would have the same binary value internally. Linked below you can find my original program if you wanted to take a look at it. I'd have no problem if you wanted to use the routines, but I don't have the docs on them anymore so it might take a little work to figure out the parameters used, it's been a long time but I might be able to help a little. http://www.atarimagazines.com/v9n2/spacestation.html Quote Link to comment Share on other sites More sharing options...
phoney Posted December 20, 2023 Author Share Posted December 20, 2023 17 hours ago, dmsc said: Hi! There are advantages and disadvantages to each option: - If you put the data inside your program, you can generate a single binary file that will load and run, this is easier to program and easier to distribute. - If you put the data as files in a disk, you can have a lot more data, as only the objects that you need would be in RAM. This will allow for more content/levels/objects, but not all at the same time. This is an example of fast drawing your image using inline DATA and MOVE (much faster than copying individual bytes): ' Image Drawing Example ' --------------------- Thank you! I will use MOVE! How much room do I have on a 48K machine for actual program text, though? If I have, say, 16x256 byte items, do the DATA statements alone use up so much space that I'll run out of RAM for my program logic when using the IDE? At the moment I'm taking the 'write it to a file, read the object I need from the appropriate file" approach. Although I could just read ALL the objects in from one big 4K file at boot ... can an array have 4096 elements? I am writing this on the 800 because I can't get the Fujinet emulator working on my other computers. Also, I just want the 'real' 800 experience. By the way, 48K 800 + LiteDos + N: driver + FB.COM works just fine. 17 hours ago, dmsc said: sample.xex 1.73 kB · 2 downloads sample.fb 1.73 kB · 1 download Quote Link to comment Share on other sites More sharing options...
dmsc Posted December 23, 2023 Share Posted December 23, 2023 Hi! On 12/20/2023 at 5:35 PM, phoney said: How much room do I have on a 48K machine for actual program text, though? About 31KB with the integer IDE - enough for a really big program. And about 32KB with the command line compiler (FBC.COM) On 12/20/2023 at 5:35 PM, phoney said: If I have, say, 16x256 byte items, do the DATA statements alone use up so much space that I'll run out of RAM for my program logic when using the IDE? No. 16x256 = 4KB of data in the executable, the DATA statements will be 16KB of text, this will fit in RAM. IMHO, start using DATA and switch to other methods when/if your program gets too big. Perhaps at that point I will have implemented the support for including DATA from disk in the IDE . On 12/20/2023 at 5:35 PM, phoney said: At the moment I'm taking the 'write it to a file, read the object I need from the appropriate file" approach. Although I could just read ALL the objects in from one big 4K file at boot ... can an array have 4096 elements? Yes, a byte array can use up all memory. On 12/20/2023 at 5:35 PM, phoney said: I am writing this on the 800 because I can't get the Fujinet emulator working on my other computers. Also, I just want the 'real' 800 experience. By the way, 48K 800 + LiteDos + N: driver + FB.COM works just fine. Great! Have Fun! Quote Link to comment Share on other sites More sharing options...
phoney Posted December 23, 2023 Author Share Posted December 23, 2023 Okay, so why isn't this working? It's putting stuff to the screen but not the same stuff in the same order as I see in the array. There should be three blank lines, followed by the first line with data being somewhat centered in the image. What's off? Quote Link to comment Share on other sites More sharing options...
dmsc Posted December 23, 2023 Share Posted December 23, 2023 Hi! 27 minutes ago, phoney said: Okay, so why isn't this working? It's putting stuff to the screen but not the same stuff in the same order as I see in the array. Because you are using a WORD array, not a BYTE array, so each array member takes two bytes. Also, it is way faster to read the data with BGET: DIM CLTHIMG(2816) BYTE OPEN #1, 4, 0, "D:SWEATER.DAT" BGET #1, &CLTHIMG, 8*32 CLOSE #1 GR.7 COLOR 1 Have Fun! Quote Link to comment Share on other sites More sharing options...
phoney Posted December 23, 2023 Author Share Posted December 23, 2023 IT WORKS! Thank you so much! I would never have figured out the 'byte/word' thing! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.